diff --git a/.gitignore b/.gitignore index ee11562f..b1580e92 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,28 @@ .DS_Store +.project examples/data *.o +*.so +*.obj +*.pdb Makefile mkmf.log -opencv.bundle \ No newline at end of file +opencv.bundle +GPATH +GRTAGS +GSYMS +GTAGS +OpenCV-* +ruby-*.*.* +ext/opencv/test.txt +pkg/ +doc/ +log.txt +videowriter_result.avi +examples/contours/rotated-boxes-with-detected-bounding-rectangles.jpg +Gemfile.lock +.yardoc +.RUBYLIBDIR.* +.RUBYARCHDIR.* +.bundle + diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..06c9f2b7 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,32 @@ +language: ruby + +sudo: false + +dist: trusty + +rvm: + - 2.3.4 + - 2.4.1 + +addons: + apt: + packages: + - libopencv-dev + +env: + global: + - PATH=/usr/lib/ccache:$PATH + +cache: + bundler: true + directories: + - $HOME/.ccache + +before_script: + - ruby ext/opencv/extconf.rb + - make + - make install + +script: + - cd test + - ruby runner.rb diff --git a/.yardopts b/.yardopts new file mode 100644 index 00000000..b41ba957 --- /dev/null +++ b/.yardopts @@ -0,0 +1,3 @@ +--load ./yard_extension.rb +ext/opencv/*.cpp + diff --git a/DEVELOPERS_NOTE.md b/DEVELOPERS_NOTE.md new file mode 100644 index 00000000..650ce343 --- /dev/null +++ b/DEVELOPERS_NOTE.md @@ -0,0 +1,137 @@ +# DEVELOPER'S NOTE + +## Requirement to develop ruby-opencv + +* OpenCV +* Git +* Microsoft Visual C++ (for mswin32) + * +* MinGW and MSYS (for mingw32) + * gcc, g++ and MSYS are needed. + * +* Some gems (see Gemfile) + * [bundler](https://github.com/carlhuda/bundler/) + * [hoe](https://github.com/seattlerb/hoe) + * [hoe-gemspec](https://github.com/flavorjones/hoe-gemspec) + * [rake-compiler](https://github.com/luislavena/rake-compiler) + + +## Create ruby-opencv gem +Run the following commands. +When you use mingw32, use **MSYS console**, or when you use mswin32, +use [**Visual Studio Command Prompt**](http://msdn.microsoft.com/en-us/library/ms229859.aspx) +instead of cmd.exe. + +``` +$ git clone git://github.com/ruby-opencv/ruby-opencv.git +$ cd ruby-opencv +$ git checkout master +$ bundle install +$ git ls-files > Manifest.txt +$ rake gem:spec +$ rake gem +``` +**ruby-opencv-x.y.z.gem** will be created in **pkg** directory. + +To create pre-build binaries, create a config file firstly: + +```yml +# config.yml +platform: mingw32 +rubies: + - C:/ruby-1.9.3-p392-mingw32/bin/ruby.exe + - C:/ruby-2.0.0-p0-mingw32/bin/ruby.exe +extopts: + - --with-opencv-include=C:/opencv/build/include + - --with-opencv-lib=C:/opencv/build/x86/mingw/lib +``` + +Entries are below: + +- **platform**: Target platform (e.g. mingw32, mswin32) +- **rubies**: Array of target versions of ruby's paths (You can create fat gems if you specify multiple versions of ruby) +- **extopts**: Array of options to be passed to **extconf.rb** + +Then, run the following command: + +``` +$ rake gem:precompile CONFIG=config.yml +``` + +**ruby-opencv-x.y.z-mingw32.gem** will be created when you use mingw32, or +**ruby-opencv-x.y.z-x86-mswin32.gem** when you use mswin32. + + +## Install ruby-opencv manually +### Linux/Mac + +``` +$ git clone git://github.com/ruby-opencv/ruby-opencv.git +$ cd ruby-opencv +$ git checkout master +$ ruby ext/opencv/extconf.rb --with-opencv-dir=/path/to/opencvdir +$ make +$ make install +``` + +Note: **/path/to/opencvdir** is the directory where you installed OpenCV. + + +### Windows (mswin32) + +Run the following commands on [**Visual Studio Command Prompt**](http://msdn.microsoft.com/en-us/library/ms229859.aspx). + +``` +$ git clone git://github.com/ruby-opencv/ruby-opencv.git +$ cd ruby-opencv +$ git checkout master +$ ruby ext/opencv/extconf.rb --with-opencv-dir=C:\path\to\opencvdir\install # for your own built OpenCV library +$ nmake +$ nmake install +``` + +To use pre-built OpenCV libraries, set the following option to extconf.rb. + +``` +$ ruby ext/opencv/extconf.rb --with-opencv-include=C:\path\to\opencvdir\build\include --with-opencv-lib=C:\path\to\opencvdir\build\x86\vc10\lib +``` + + +### Windows (mingw32) + +Run the following commands on **MSYS console**. + +``` +$ git clone git://github.com/ruby-opencv/ruby-opencv.git +$ cd ruby-opencv +$ git checkout master +$ ruby ext/opencv/extconf.rb --with-opencv-dir=/C/path/to/opencvdir/install # for your own built OpenCV library +$ make +$ make install +``` + +To use pre-built OpenCV libraries, set the following option to extconf.rb. + +``` +$ ruby ext/opencv/extconf.rb --with-opencv-include=/c/path/to/opencvdir/build/include --with-opencv-lib=/c/path/to/opencvdir/build/x86/mingw/lib +``` + + +## Run tests + +To run all tests, run **test/runner.rb** + +``` +$ cd ruby-opencv/test +$ ruby runner.rb +``` + +To run tests of the specified function, run a specific test with --name option. + +The following sample runs tests for CvMat#initialize + +``` +$ cd ruby-opencv/test +$ ruby test_cvmat.rb --name=test_initialize +``` + diff --git a/Gemfile b/Gemfile new file mode 100644 index 00000000..0cb99e26 --- /dev/null +++ b/Gemfile @@ -0,0 +1,9 @@ +source 'https://rubygems.org' + +group :development do + gem "hoe" + gem "hoe-gemspec" + gem "rake-compiler" + gem "yard" +end + diff --git a/License.txt b/License.txt index 9261a652..896d1469 100644 --- a/License.txt +++ b/License.txt @@ -1,4 +1,4 @@ -The BSD Liscense +The BSD License Copyright (c) 2008, Masakazu Yonekura All rights reserved. diff --git a/Manifest.txt b/Manifest.txt index b7477d89..c48551b4 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -1,115 +1,239 @@ +.gitignore +.yardopts +DEVELOPERS_NOTE.md +Gemfile History.txt -Manifest.txt -README.txt License.txt +Manifest.txt +README.md Rakefile +config.yml +examples/alpha_blend.rb +examples/contours/bitmap-contours-with-labels.png +examples/contours/bitmap-contours.png +examples/contours/bounding-box-detect-canny.rb +examples/contours/contour_retrieval_modes.rb +examples/contours/rotated-boxes.jpg examples/convexhull.rb examples/face_detect.rb +examples/facerec/create_csv.rb +examples/facerec/facerec_eigenfaces.rb +examples/facerec/facerec_fisherfaces.rb +examples/facerec/facerec_lbph.rb +examples/facerec/readme.md +examples/find_obj.rb examples/houghcircle.rb -examples/inpaint.png +examples/images/box.png +examples/images/box_in_scene.png +examples/images/inpaint.png +examples/images/lena-256x256.jpg +examples/images/lena-eyes.jpg +examples/images/lenna-rotated.jpg +examples/images/lenna.jpg +examples/images/stuff.jpg +examples/images/tiffany.jpg examples/inpaint.rb +examples/match_kdtree.rb +examples/match_template.rb examples/paint.rb examples/snake.rb -examples/stuff.jpg -ext/curve.cpp -ext/curve.h -ext/cvavgcomp.cpp -ext/cvavgcomp.h -ext/cvbox2d.cpp -ext/cvbox2d.h -ext/cvcapture.cpp -ext/cvcapture.h -ext/cvchain.cpp -ext/cvchain.h -ext/cvchaincode.cpp -ext/cvchaincode.h -ext/cvcircle32f.cpp -ext/cvcircle32f.h -ext/cvcondensation.cpp -ext/cvcondensation.h -ext/cvconnectedcomp.cpp -ext/cvconnectedcomp.h -ext/cvcontour.cpp -ext/cvcontour.h -ext/cvcontourtree.cpp -ext/cvcontourtree.h -ext/cvconvexitydefect.cpp -ext/cvconvexitydefect.h -ext/cverror.cpp -ext/cverror.h -ext/cvfont.cpp -ext/cvfont.h -ext/cvhaarclassifiercascade.cpp -ext/cvhaarclassifiercascade.h -ext/cvhistogram.cpp -ext/cvhistogram.h -ext/cvindex.cpp -ext/cvindex.h -ext/cvline.cpp -ext/cvline.h -ext/cvmat.cpp -ext/cvmat.h -ext/cvmatnd.cpp -ext/cvmatnd.h -ext/cvmemstorage.cpp -ext/cvmemstorage.h -ext/cvmoments.cpp -ext/cvmoments.h -ext/cvpoint.cpp -ext/cvpoint.h -ext/cvpoint2d32f.cpp -ext/cvpoint2d32f.h -ext/cvpoint3d32f.cpp -ext/cvpoint3d32f.h -ext/cvrect.cpp -ext/cvrect.h -ext/cvscalar.cpp -ext/cvscalar.h -ext/cvseq.cpp -ext/cvseq.h -ext/cvset.cpp -ext/cvset.h -ext/cvsize.cpp -ext/cvsize.h -ext/cvsize2d32f.cpp -ext/cvsize2d32f.h -ext/cvslice.cpp -ext/cvslice.h -ext/cvsparsemat.cpp -ext/cvsparsemat.h -ext/cvtermcriteria.cpp -ext/cvtermcriteria.h -ext/cvtwopoints.cpp -ext/cvtwopoints.h -ext/cvvector.cpp -ext/cvvector.h -ext/cvvideowriter.cpp -ext/cvvideowriter.h -ext/extconf.rb -ext/gui.cpp -ext/gui.h -ext/iplconvkernel.cpp -ext/iplconvkernel.h -ext/iplimage.cpp -ext/iplimage.h -ext/mouseevent.cpp -ext/mouseevent.h -ext/opencv.cpp -ext/opencv.h -ext/point3dset.cpp -ext/point3dset.h -ext/pointset.cpp -ext/pointset.h -ext/trackbar.cpp -ext/trackbar.h -ext/window.cpp -ext/window.h +ext/opencv/algorithm.cpp +ext/opencv/algorithm.h +ext/opencv/curve.cpp +ext/opencv/curve.h +ext/opencv/cvavgcomp.cpp +ext/opencv/cvavgcomp.h +ext/opencv/cvbox2d.cpp +ext/opencv/cvbox2d.h +ext/opencv/cvcapture.cpp +ext/opencv/cvcapture.h +ext/opencv/cvchain.cpp +ext/opencv/cvchain.h +ext/opencv/cvcircle32f.cpp +ext/opencv/cvcircle32f.h +ext/opencv/cvconnectedcomp.cpp +ext/opencv/cvconnectedcomp.h +ext/opencv/cvcontour.cpp +ext/opencv/cvcontour.h +ext/opencv/cvcontourtree.cpp +ext/opencv/cvcontourtree.h +ext/opencv/cvconvexitydefect.cpp +ext/opencv/cvconvexitydefect.h +ext/opencv/cverror.cpp +ext/opencv/cverror.h +ext/opencv/cvfeaturetree.cpp +ext/opencv/cvfeaturetree.h +ext/opencv/cvfont.cpp +ext/opencv/cvfont.h +ext/opencv/cvhaarclassifiercascade.cpp +ext/opencv/cvhaarclassifiercascade.h +ext/opencv/cvhistogram.cpp +ext/opencv/cvhistogram.h +ext/opencv/cvhumoments.cpp +ext/opencv/cvhumoments.h +ext/opencv/cvline.cpp +ext/opencv/cvline.h +ext/opencv/cvmat.cpp +ext/opencv/cvmat.h +ext/opencv/cvmemstorage.cpp +ext/opencv/cvmemstorage.h +ext/opencv/cvmoments.cpp +ext/opencv/cvmoments.h +ext/opencv/cvpoint.cpp +ext/opencv/cvpoint.h +ext/opencv/cvpoint2d32f.cpp +ext/opencv/cvpoint2d32f.h +ext/opencv/cvpoint3d32f.cpp +ext/opencv/cvpoint3d32f.h +ext/opencv/cvrect.cpp +ext/opencv/cvrect.h +ext/opencv/cvscalar.cpp +ext/opencv/cvscalar.h +ext/opencv/cvseq.cpp +ext/opencv/cvseq.h +ext/opencv/cvsize.cpp +ext/opencv/cvsize.h +ext/opencv/cvsize2d32f.cpp +ext/opencv/cvsize2d32f.h +ext/opencv/cvslice.cpp +ext/opencv/cvslice.h +ext/opencv/cvsurfparams.cpp +ext/opencv/cvsurfparams.h +ext/opencv/cvsurfpoint.cpp +ext/opencv/cvsurfpoint.h +ext/opencv/cvtermcriteria.cpp +ext/opencv/cvtermcriteria.h +ext/opencv/cvtwopoints.cpp +ext/opencv/cvtwopoints.h +ext/opencv/cvutils.cpp +ext/opencv/cvutils.h +ext/opencv/cvvideowriter.cpp +ext/opencv/cvvideowriter.h +ext/opencv/eigenfaces.cpp +ext/opencv/eigenfaces.h +ext/opencv/extconf.rb +ext/opencv/facerecognizer.cpp +ext/opencv/facerecognizer.h +ext/opencv/fisherfaces.cpp +ext/opencv/fisherfaces.h +ext/opencv/gui.cpp +ext/opencv/gui.h +ext/opencv/iplconvkernel.cpp +ext/opencv/iplconvkernel.h +ext/opencv/iplimage.cpp +ext/opencv/iplimage.h +ext/opencv/lbph.cpp +ext/opencv/lbph.h +ext/opencv/mouseevent.cpp +ext/opencv/mouseevent.h +ext/opencv/opencv.cpp +ext/opencv/opencv.h +ext/opencv/pointset.cpp +ext/opencv/pointset.h +ext/opencv/trackbar.cpp +ext/opencv/trackbar.h +ext/opencv/window.cpp +ext/opencv/window.h images/CvMat_sobel.png images/CvMat_sub_rect.png images/CvSeq_relationmap.png -images/face_detect_from_lena.jpg lib/opencv.rb -lib/version.rb -setup/setup.cygwin.rb -setup/setup.mingw.rb -setup/setup.mswin32.rb +lib/opencv/psyched_yaml.rb +lib/opencv/version.rb +ruby-opencv.gemspec +test/eigenfaces_save.xml +test/fisherfaces_save.xml +test/helper.rb +test/lbph_save.xml +test/runner.rb +test/samples/airplane.jpg +test/samples/baboon.jpg +test/samples/baboon200.jpg +test/samples/baboon200_rotated.jpg +test/samples/blank0.jpg +test/samples/blank1.jpg +test/samples/blank2.jpg +test/samples/blank3.jpg +test/samples/blank4.jpg +test/samples/blank5.jpg +test/samples/blank6.jpg +test/samples/blank7.jpg +test/samples/blank8.jpg +test/samples/blank9.jpg +test/samples/cat.jpg +test/samples/chessboard.jpg +test/samples/contours.jpg +test/samples/fruits.jpg +test/samples/haarcascade_frontalface_alt.xml.gz +test/samples/inpaint-mask.bmp +test/samples/lena-256x256.jpg +test/samples/lena-32x32.jpg +test/samples/lena-eyes.jpg +test/samples/lena-inpaint.jpg +test/samples/lena.jpg +test/samples/lines.jpg +test/samples/messy0.jpg +test/samples/messy1.jpg +test/samples/movie_sample.avi +test/samples/one_way_train_0000.jpg +test/samples/one_way_train_0001.jpg +test/samples/partially_blank0.jpg +test/samples/partially_blank1.jpg +test/samples/smooth0.jpg +test/samples/smooth1.jpg +test/samples/smooth2.jpg +test/samples/smooth3.jpg +test/samples/smooth4.jpg +test/samples/smooth5.jpg +test/samples/smooth6.jpg +test/samples/str-cv-rotated.jpg +test/samples/str-cv.jpg +test/samples/str-ov.jpg +test/samples/stuff.jpg +test/test_curve.rb +test/test_cvavgcomp.rb +test/test_cvbox2d.rb +test/test_cvcapture.rb +test/test_cvchain.rb +test/test_cvcircle32f.rb +test/test_cvconnectedcomp.rb +test/test_cvcontour.rb +test/test_cvcontourtree.rb +test/test_cverror.rb +test/test_cvfeaturetree.rb +test/test_cvfont.rb +test/test_cvhaarclassifiercascade.rb +test/test_cvhistogram.rb +test/test_cvhumoments.rb +test/test_cvline.rb +test/test_cvmat.rb +test/test_cvmat_drawing.rb +test/test_cvmat_dxt.rb +test/test_cvmat_imageprocessing.rb +test/test_cvmoments.rb +test/test_cvpoint.rb +test/test_cvpoint2d32f.rb +test/test_cvpoint3d32f.rb +test/test_cvrect.rb +test/test_cvscalar.rb +test/test_cvseq.rb +test/test_cvsize.rb +test/test_cvsize2d32f.rb +test/test_cvslice.rb +test/test_cvsurfparams.rb +test/test_cvsurfpoint.rb +test/test_cvtermcriteria.rb +test/test_cvtwopoints.rb +test/test_cvvideowriter.rb +test/test_eigenfaces.rb +test/test_fisherfaces.rb +test/test_iplconvkernel.rb +test/test_iplimage.rb +test/test_lbph.rb +test/test_mouseevent.rb +test/test_opencv.rb +test/test_pointset.rb +test/test_preliminary.rb +test/test_trackbar.rb +test/test_window.rb +yard_extension.rb diff --git a/README.md b/README.md new file mode 100644 index 00000000..50ffc435 --- /dev/null +++ b/README.md @@ -0,0 +1,94 @@ +![Build Status with Travis CI](https://travis-ci.org/ruby-opencv/ruby-opencv.svg?branch=master) + +# ruby-opencv + +An OpenCV wrapper for Ruby. + +* Web site: +* Ruby 2.x and OpenCV 2.4.13 are supported. +* [Documentation](http://www.rubydoc.info/gems/ruby-opencv/frames) + +## Requirement + +* OpenCV + * [Download](http://sourceforge.net/projects/opencvlibrary/) + * [Install guide](http://docs.opencv.org/doc/tutorials/introduction/table_of_content_introduction/table_of_content_introduction.html#table-of-content-introduction) + +## Install +### Linux/Mac +1. Install [OpenCV](http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/) +2. Install ruby-opencv + +``` +$ gem install ruby-opencv -- --with-opencv-dir=/path/to/opencvdir +``` + +Note: **/path/to/opencvdir** is the directory where you installed OpenCV. + + +### Windows (RubyInstaller) + +See [install-ruby-opencv-with-rubyinstaller-on-windows.md](install-ruby-opencv-with-rubyinstaller-on-windows.md). + +## Sample code +### Load and Display an Image + +A sample to load and display an image. An equivalent code of [this tutorial](http://docs.opencv.org/doc/tutorials/introduction/display_image/display_image.html#display-image). + +```ruby +require 'opencv' +include OpenCV + +if ARGV.size == 0 + puts "Usage: ruby #{__FILE__} ImageToLoadAndDisplay" + exit +end + +image = nil +begin + image = CvMat.load(ARGV[0], CV_LOAD_IMAGE_COLOR) # Read the file. +rescue + puts 'Could not open or find the image.' + exit +end + +window = GUI::Window.new('Display window') # Create a window for display. +window.show(image) # Show our image inside it. +GUI::wait_key # Wait for a keystroke in the window. +``` + +### Face Detection + +A sample to detect faces from an image. + +```ruby +require 'opencv' +include OpenCV + +if ARGV.length < 2 + puts "Usage: ruby #{__FILE__} source dest" + exit +end + +data = './data/haarcascades/haarcascade_frontalface_alt.xml' +detector = CvHaarClassifierCascade::load(data) +image = CvMat.load(ARGV[0]) +detector.detect_objects(image).each do |region| + color = CvColor::Blue + image.rectangle! region.top_left, region.bottom_right, :color => color +end + +image.save_image(ARGV[1]) +window = GUI::Window.new('Face detection') +window.show(image) +GUI::wait_key +``` + +For more samples, see examples/*.rb + +## LICENSE: + +The BSD Liscense + +see LICENSE.txt + diff --git a/README.rdoc b/README.rdoc deleted file mode 100644 index fa57b975..00000000 --- a/README.rdoc +++ /dev/null @@ -1,94 +0,0 @@ -= opencv - -The initial Open Computer Vision library was originally developed by Intel -Corporation. Recent development has been headed by Willow Garage, Inc. - -Current OpenCV Sourceforge Project -http://opencv.willowgarage.com/wiki/ - -Earlier OpenCV Sourceforge Project -http://sourceforge.net/projects/opencvlibrary/ - -Ruby/OpenCV Author's Web Page -http://blueruby.mydns.jp/opencv - -== DESCRIPTION: - -OpenCV Ruby Wrapper - -== FEATURES/PROBLEMS: - -* First release rubygems, Some OpenCV functions wrapped. - -== DEPENDENCIES: - -This gem relies on the OpenCV project. There are a number of ways to install -the library. Building the latest from source is preferred on OSX: - - http://opencv.willowgarage.com/wiki/Mac_OS_X_OpenCV_Port - -This also contains the data for the default cascades. - -== INSTALLATION: - -You can install by cloning this repository: - - git clone git://github.com/jeffrafter/ruby-opencv.git - -Then inside the ruby-opencv folder run: - - ruby ext/extconf.rb - make - sudo make install - -== SYNOPSIS: - -Once installed it is possible to show images via GUI Window. - - require "rubygems" - gem "opencv" - require "opencv" - - image = OpenCV::IplImage.load("sample.jpg") - window = OpenCV::GUI::Window.new("preview") - window.show(image) - OpenCV::GUI::wait_key - -For more samples, see examples/*.rb - -== FACE DETECTION: - -Here is a sample face detection program that doesn't rely on the GUI components. -In order for this to work you must copy the OpenCV haarcascades data into a -subfolder called data. - - #!/usr/bin/env ruby - require "rubygems" - require "opencv" - - if ARGV.length < 2 - puts "Usage: your_app_name source dest" - exit - end - - data = "./data/haarcascades/haarcascade_frontalface_alt.xml" - detector = OpenCV::CvHaarClassifierCascade::load(data) - image = OpenCV::IplImage.load(ARGV[0]) - detector.detect_objects(image) do |region| - color = OpenCV::CvColor::Blue - image.rectangle! region.top_left, region.bottom_right, :color => color - end - image.save_image(ARGV[1]) - -== REQUIREMENTS: - -* OpenCV 2.0 or later. - http://opencv.willowgarage.com/wiki/ -* ffcall (optional) - http://www.haible.de/bruno/packages-ffcall.html - -== LICENSE: - -The BSD Liscense - -see LICENSE.txt diff --git a/Rakefile b/Rakefile index f90e03a1..058f0901 100644 --- a/Rakefile +++ b/Rakefile @@ -1,34 +1,99 @@ -# -*- ruby -*- - +# -*- mode: ruby; coding: utf-8 -*- require 'rubygems' +require "rubygems/ext" +require "rubygems/installer" require 'hoe' -require './lib/version' - -Hoe.new('opencv', OpenCV::VERSION) do |p| - p.author = ['Masakazu Yonekura'] - p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n") - p.description = < %w{ext/extconf.rb} +require 'rake/extensiontask' +require 'fileutils' +require './lib/opencv/psyched_yaml' +require 'yard' +require 'yard/rake/yardoc_task' +require './yard_extension' + +SO_FILE = 'opencv.so' + +Hoe.plugin :gemspec + +hoespec = Hoe.spec 'ruby-opencv' do |s| + s.summary = 'OpenCV wrapper for Ruby' + s.description = 'ruby-opencv is a wrapper of OpenCV for Ruby. It helps you to write computer vision programs (e.g. detecting faces from pictures) with Ruby.' + s.licenses = ['BSD-3-Clause'] + s.developer('lsxi', 'masakazu.yonekura@gmail.com') + s.developer('ser1zw', 'azariahsawtikes@gmail.com') + s.developer('pcting', 'pcting@gmail.com') + + s.readme_file = 'README.md' + s.history_file = 'History.txt' + + s.spec_extras = { :extensions => ['ext/opencv/extconf.rb'] } + + s.test_globs = ['test/test_*.rb'] + s.urls = ['https://github.com/ruby-opencv/ruby-opencv/'] + + s.extra_dev_deps << ['rake-compiler', '~> 0'] << ['hoe-gemspec', '~> 0'] + + Rake::ExtensionTask.new('opencv', spec) do |ext| + ext.lib_dir = 'lib' + end +end + +hoespec.spec.files.delete('.gemtest') + +Rake::Task[:test].prerequisites << :compile + +desc 'Create a pre-compiled gem' +task 'gem:precompile' => ['gem'] do + tmp_dir = Dir.mktmpdir('tmp', '.') + gemfile = Dir.glob("pkg/*.gem")[0] + target_dir = File.join(tmp_dir, File.basename(gemfile, '.gem')) + + installer = Gem::Installer.new(gemfile) + installer.unpack(target_dir) + + gemspec = installer.spec + extension = gemspec.extensions[0] + gemspec.extensions.clear + + config = ENV['CONFIG'] ? YAML.load_file(ENV['CONFIG']) : {} + rubies = config['rubies'] || [Gem.ruby] + args = config['extopts'] || [] + gemspec.platform = config['platform'] || Gem::Platform::CURRENT + + multi = rubies.size > 1 + rubies.each { |ruby| + lib_dir = 'lib' + if multi + major, minor, _ = `#{ruby} -e "print RUBY_VERSION"`.chomp.split('.') + lib_dir = File.join(lib_dir, [major, minor].join('.')) + end + + make_cmd = (`#{ruby} -e "print RUBY_PLATFORM"` =~ /mswin/) ? 'nmake' : 'make' + Dir.chdir(target_dir) { + cmd = [ruby, extension, *args].join(' ') + results = [] + Gem::Ext::ExtConfBuilder.run(cmd, results) + Gem::Ext::ExtConfBuilder.make('', results) + + FileUtils.mkdir_p lib_dir + FileUtils.mv SO_FILE, lib_dir + sh "#{make_cmd} clean" + } + + gemspec.files << File.join(lib_dir, SO_FILE) } - p.summary = 'OpenCV wrapper for Ruby.' - # p.test_globs = 'spec/**/*_spec.rb' - p.clean_globs |= ['*.o'] - - p.url = 'http://blueruby.mydns.jp/opencv' - - p.extra_deps << ['hoe'] + + Dir.chdir(target_dir) { + gemfile = Gem::Package.build(gemspec) + FileUtils.mv gemfile, File.dirname(__FILE__) + } + + FileUtils.rm_rf tmp_dir end -# vim: syntax=Ruby +# yard +YARD::Rake::YardocTask.new do |t| + t.files = ['lib/**/*.rb', 'ext/**/*.cpp'] +end + +# vim: syntax=ruby + diff --git a/config.yml b/config.yml new file mode 100644 index 00000000..4034d688 --- /dev/null +++ b/config.yml @@ -0,0 +1,7 @@ +platform: mingw32 +rubies: + - C:/ruby-1.9.3-p392-mingw32/bin/ruby.exe + - C:/ruby-2.0.0-p0-mingw32/bin/ruby.exe +extopts: + - --with-opencv-include=C:/opencv/build/include + - --with-opencv-lib=C:/opencv/build/x86/mingw/lib diff --git a/examples/alpha_blend.rb b/examples/alpha_blend.rb new file mode 100755 index 00000000..e65331a3 --- /dev/null +++ b/examples/alpha_blend.rb @@ -0,0 +1,21 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- + +# Alpha blending sample with GUI + +require 'opencv' +include OpenCV + +img1 = IplImage.load('images/lenna.jpg', CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) +img2 = IplImage.load('images/tiffany.jpg', CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + +window = GUI::Window.new('Alpha blend') +max = 100.0 +val = max / 2.0 +window.set_trackbar("Alpha", max, val) { |v| + a = v.to_f / max + window.show CvMat.add_weighted(img1, a, img2, 1.0 - a, 0) +} +window.show CvMat.add_weighted(img1, val / max, img2, 1.0 - val / max, 0) +GUI::wait_key + diff --git a/examples/contours/bitmap-contours-with-labels.png b/examples/contours/bitmap-contours-with-labels.png new file mode 100644 index 00000000..674050ae Binary files /dev/null and b/examples/contours/bitmap-contours-with-labels.png differ diff --git a/examples/contours/bitmap-contours.png b/examples/contours/bitmap-contours.png new file mode 100644 index 00000000..4890a4e5 Binary files /dev/null and b/examples/contours/bitmap-contours.png differ diff --git a/examples/contours/bounding-box-detect-canny.rb b/examples/contours/bounding-box-detect-canny.rb new file mode 100755 index 00000000..e0d3b6f8 --- /dev/null +++ b/examples/contours/bounding-box-detect-canny.rb @@ -0,0 +1,62 @@ +#!/usr/bin/env ruby +# +# Detects contours in an image and +# their boundingboxes +# +require "opencv" + +# Load image +cvmat = OpenCV::CvMat.load("rotated-boxes.jpg") + +# The "canny" edge-detector does only work with grayscale images +# so to be sure, convert the image +# otherwise you will get an OpenCV::CvStsAssert exception. +cvmat = cvmat.BGR2GRAY + +# Use the "canny" edge detection algorithm (http://en.wikipedia.org/wiki/Canny_edge_detector) +# Parameters are two colors that are then used to determine possible corners +canny = cvmat.canny(50, 150) + +# Look for contours +# We want them to be returned as a flat list (CV_RETR_LIST) and simplified (CV_CHAIN_APPROX_SIMPLE) +# Both are the defaults but included here for clarity +contour = canny.find_contours(:mode => OpenCV::CV_RETR_LIST, :method => OpenCV::CV_CHAIN_APPROX_SIMPLE) + +# The Canny Algorithm returns two matches for every contour (see O'Reilly: Learning OpenCV Page 235) +# We need only the external edges so we ignore holes. +# When there are no more contours, contours.h_next will return nil +while contour + # No "holes" please (aka. internal contours) + unless contour.hole? + + puts '-' * 80 + puts "BOUNDING RECT FOUND" + puts '-' * 80 + + # You can detect the "bounding rectangle" which is always oriented horizontally and vertically + box = contour.bounding_rect + puts "found external contour with bounding rectangle from #{box.top_left.x},#{box.top_left.y} to #{box.bottom_right.x},#{box.bottom_right.y}" + + # The contour area can be computed: + puts "that contour encloses an area of #{contour.contour_area} square pixels" + + # .. as can be the length of the contour + puts "that contour is #{contour.arc_length} pixels long " + + # Draw that bounding rectangle + cvmat.rectangle! box.top_left, box.bottom_right, :color => OpenCV::CvColor::Black + + # You can also detect the "minimal rectangle" which has an angle, width, height and center coordinates + # and is not neccessarily horizonally or vertically aligned. + # The corner of the rectangle with the lowest y and x position is the anchor (see image here: http://bit.ly/lT1XvB) + # The zero angle position is always straight up. + # Positive angle values are clockwise and negative values counter clockwise (so -60 means 60 degree counter clockwise) + box = contour.min_area_rect2 + puts "found minimal rectangle with its center at (#{box.center.x.round},#{box.center.y.round}), width of #{box.size.width.round}px, height of #{box.size.height.round} and an angle of #{box.angle.round} degree" + end + contour = contour.h_next +end + +# And save the image +puts "\nSaving image with bounding rectangles" +cvmat.save_image("rotated-boxes-with-detected-bounding-rectangles.jpg") diff --git a/examples/contours/contour_retrieval_modes.rb b/examples/contours/contour_retrieval_modes.rb new file mode 100755 index 00000000..929b42cd --- /dev/null +++ b/examples/contours/contour_retrieval_modes.rb @@ -0,0 +1,139 @@ +#!/usr/bin/env ruby +# +# This file shows the different retrieval modes for contour detection +# +require "opencv" + +# Load image +# The structure of the image is "explained" in bitmap-contours-with-labels.png +cvmat = OpenCV::CvMat.load("bitmap-contours.png") + +# "find_contours" does only operate on bitmap images (black/white) +mat = OpenCV::CvMat.new(cvmat.rows, cvmat.cols, :cv8u, 1) +(cvmat.rows * cvmat.cols).times do |i| + mat[i] = (cvmat[i][0] <= 128) ? OpenCV::CvScalar.new(0) : OpenCV::CvScalar.new(255) +end + +# find_contours takes two parameters: +# 1. Retrieval mode (:mode, defines the structure of the contour sequence returned) +# - CV_RETR_LIST (default) +# - CV_RETR_EXTERNAL +# - CV_RETR_CCOMP +# - CV_RETR_TREE +# 2. Retrieval Method (:method, how the contours are approximated) +# - CV_CHAIN_CODE +# - CV_CHAIN_APPROX_NONE +# - CV_CHAIN_APPROX_SIMPLE (default) +# - CV_CHAIN_APPROX_TC89_L1 +# - CV_CHAIN_APPROX_T89_KCOS +# - CV_LINK_RUNS + +# +# The default: CV_RETR_LIST and CV_CHAIN_APPROX_SIMPLE +# This produces a flat list of contours that can be traversed with .h_next and .h_prev +# +puts "Detecting using CV_RETR_LIST and CV_CHAIN_APPROX_SIMPLE" +contour = mat.find_contours(:mode => OpenCV::CV_RETR_LIST, :method => OpenCV::CV_CHAIN_APPROX_SIMPLE) +cindex=1 + +while contour + puts "Contour ##{cindex} is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})" + contour = contour.h_next + cindex+=1 +end + +# +# CV_RETR_EXTERNAL retrieves only the outer most non "hole" contour +# +puts '-'*80 +puts "Detecting using CV_RETR_EXTERNAL and CV_CHAIN_APPROX_SIMPLE" +contour = mat.find_contours(:mode => OpenCV::CV_RETR_EXTERNAL, :method => OpenCV::CV_CHAIN_APPROX_SIMPLE) +cindex=1 + +while contour + puts "Contour ##{cindex} is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})" + contour = contour.h_next + cindex+=1 +end + +# +# CV_RETR_CCOMP organizes the contours in a two level deep stack +# The first level holds the contours +# The second level contains the holes of the contours in level 1 +# +# C00001 <-> C00000 <-> C000 <-> C0 +# | | +# V V +# H0000 H00 +# +puts '-'*80 +puts "Detecting using CV_RETR_CCOMP and CV_CHAIN_APPROX_SIMPLE" +contour = mat.find_contours(:mode => OpenCV::CV_RETR_CCOMP, :method => OpenCV::CV_CHAIN_APPROX_SIMPLE) + +# C00001 +puts "Contour #1 is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})" +contour = contour.h_next + +# C00000 +puts "Contour #2 is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})" +contour = contour.h_next + +# C000 +puts "Contour #3 is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})" +contour_down = contour.v_next + +# H0000 +puts "Contour #4 is #{contour_down.contour_area} px^2 (width: #{contour_down.bounding_rect.width}, height: #{contour_down.bounding_rect.height}, type: #{(contour_down.hole?)?"hole":"contour"})" +contour = contour.h_next + +# C0 +puts "Contour #5 is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})" +contour_down = contour.v_next + +# H00 +puts "Contour #6 is #{contour_down.contour_area} px^2 (width: #{contour_down.bounding_rect.width}, height: #{contour_down.bounding_rect.height}, type: #{(contour_down.hole?)?"hole":"contour"})" + +# +# CV_RETR_TREE manages the contours in a tree structure +# This reconstructs the complete hierarchy of contours and holes that the image displayed +# +# C0 +# | +# V +# H00 +# | +# V +# C000 +# | +# V +# H0000-------+ +# | | +# V V +# C00000 C00001 +# +puts '-'*80 +puts "Detecting using CV_RETR_TREE and CV_CHAIN_APPROX_SIMPLE" +contour = mat.find_contours(:mode => OpenCV::CV_RETR_TREE, :method => OpenCV::CV_CHAIN_APPROX_SIMPLE) + +# C0 +puts "Contour #1 is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})" +contour = contour.v_next + +# H00 +puts "Contour #2 is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})" +contour = contour.v_next + +# C000 +puts "Contour #3 is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})" +contour = contour.v_next + +# H0000 +puts "Contour #4 is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})" +contour = contour.v_next + +# C00000 +puts "Contour #5 is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})" +contour_right = contour.h_next + +# C00001 +puts "Contour #6 is #{contour_right.contour_area} px^2 (width: #{contour_right.bounding_rect.width}, height: #{contour_right.bounding_rect.height}, type: #{(contour_right.hole?)?"hole":"contour"})" diff --git a/examples/contours/rotated-boxes.jpg b/examples/contours/rotated-boxes.jpg new file mode 100644 index 00000000..cf3a2e6f Binary files /dev/null and b/examples/contours/rotated-boxes.jpg differ diff --git a/examples/convexhull.rb b/examples/convexhull.rb index 23d9afa9..628595d1 100755 --- a/examples/convexhull.rb +++ b/examples/convexhull.rb @@ -1,41 +1,47 @@ #!/usr/bin/env ruby # convexhull.rb -gem "opencv" +# Draw contours and convexity defect points to captured image +require "rubygems" require "opencv" -require "pp" include OpenCV window = GUI::Window.new("convexhull") -pp CvCapture::INTERFACE capture = CvCapture::open -accuracy = 0.1 -t = window.set_trackbar("accuracy", 100, 1){|v| - accuracy = 0.1 * v +accuracy = 1 +t = window.set_trackbar("accuracy", 10, 1) { |v| + accuracy = v } -while true - key = GUI::wait_key(1) +circle_options = { :color => CvColor::Blue, :line_type => :aa, :thickness => -1 } + +loop do image = capture.query + + # Calculate contours from a binary image gray = image.BGR2GRAY - bin = gray.threshold_binary(0x44, 0xFF) - contours = bin.find_contours - while contours - image.poly_line! contours.approx(:accuracy => accuracy), :color => CvScalar::Red - contours.convexity_defects.each{|cd| - image.circle! cd.start, 1, :color => CvScalar::Blue - image.circle! cd.end, 1, :color => CvScalar::Blue - image.circle! cd.depth_point, 1, :color => CvScalar::Blue - } + bin = gray.threshold(0x44, 0xFF, :binary) + contours = bin.find_contours + + while contours + # Draw contours + poly = contours.approx(:accuracy => accuracy) + begin + image.draw_contours!(poly, CvColor::Red, CvColor::Black, 2, + :thickness => 2, :line_type => :aa) + end while (poly = poly.h_next) + # Draw convexity defects + hull = contours.convex_hull2(true, false) + contours.convexity_defects(hull).each { |cd| + image.circle!(cd.start, 3, circle_options) + image.circle!(cd.depth_point, 3, circle_options) + image.circle!(cd.end, 3, circle_options) + } contours = contours.h_next end - #pts = gray.good_features_to_track(0.01, 10) - #puts pts.length - window.show image - next unless key - case key.chr - when "\e" - exit - end + + window.show image + exit if GUI::wait_key(1) end + diff --git a/examples/face_detect.rb b/examples/face_detect.rb index defe1dd6..153db6c8 100755 --- a/examples/face_detect.rb +++ b/examples/face_detect.rb @@ -1,25 +1,20 @@ #!/usr/bin/env ruby # face_detect.rb require "rubygems" -gem "opencv" require "opencv" include OpenCV window = GUI::Window.new("face detect") capture = CvCapture.open -detector = CvHaarClassifierCascade::load("C:/Program Files/OpenCV/data/haarcascades/haarcascade_frontalface_alt.xml") +detector = CvHaarClassifierCascade::load("./data/haarcascades/haarcascade_frontalface_alt.xml") -while true - key = GUI::wait_key(1) +loop { image = capture.query - detector.detect_objects(image){|i| - image.rectangle! i.top_left, i.bottom_right, :color => CvColor::Red + detector.detect_objects(image).each { |rect| + image.rectangle! rect.top_left, rect.bottom_right, :color => CvColor::Red } window.show image - next unless key - case key.chr - when "\e" - exit - end -end + break if GUI::wait_key(100) +} + diff --git a/examples/facerec/create_csv.rb b/examples/facerec/create_csv.rb new file mode 100755 index 00000000..9081e0b1 --- /dev/null +++ b/examples/facerec/create_csv.rb @@ -0,0 +1,43 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- + +# This is a tiny script to help you creating a CSV file from a face +# database with a similar hierarchie: +# +# philipp@mango:~/facerec/data/at$ tree +# . +# |-- README +# |-- s1 +# | |-- 1.pgm +# | |-- ... +# | |-- 10.pgm +# |-- s2 +# | |-- 1.pgm +# | |-- ... +# | |-- 10.pgm +# ... +# |-- s40 +# | |-- 1.pgm +# | |-- ... +# | |-- 10.pgm +# +# See http://docs.opencv.org/trunk/modules/contrib/doc/facerec/facerec_tutorial.html +# +if ARGV.size != 1 + puts "usage: ruby #{__FILE__} " + exit +end + +BASE_PATH = ARGV[0] +SEPARATOR = ';' + +label = 0 +Dir.glob("#{BASE_PATH}/*").each { |dir| + if FileTest::directory? dir + Dir.glob("#{dir}/*") { |filename| + puts "#{filename}#{SEPARATOR}#{label}" + } + label += 1 + end +} + diff --git a/examples/facerec/facerec_eigenfaces.rb b/examples/facerec/facerec_eigenfaces.rb new file mode 100755 index 00000000..866529b9 --- /dev/null +++ b/examples/facerec/facerec_eigenfaces.rb @@ -0,0 +1,132 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- + +# Eigenfaces sample in ruby-opencv, equivalent to http://docs.opencv.org/trunk/_downloads/facerec_eigenfaces.cpp +# See http://docs.opencv.org/trunk/modules/contrib/doc/facerec/facerec_tutorial.html +require 'opencv' +include OpenCV + +def norm_0_255(src) + dst = nil + case src.channel + when 1 + dst = src.normalize(0, 255, CV_NORM_MINMAX, CV_8UC1) + when 2 + dst = src.normalize(0, 255, CV_NORM_MINMAX, CV_8UC3) + else + dst = src.copy + end + + dst +end + +def read_csv(filename, sepalator = ';') + images = [] + labels = [] + open(filename, 'r') { |f| + f.each { |line| + path, label = line.chomp.split(sepalator) + images << CvMat.load(path, CV_LOAD_IMAGE_GRAYSCALE) + labels << label.to_i + } + } + + [images, labels] +end + +if ARGV.size < 1 + puts "usage: ruby #{__FILE__} " + exit 1 +end +fn_csv = ARGV.shift +output_folder = ARGV.shift + +images, labels = read_csv(fn_csv); + +height = images[0].rows; + +# The following lines simply get the last images from your dataset and remove it +# from the vector. This is done, so that the training data (which we learn the +# cv::FaceRecognizer on) and the test data we test the model with, do not overlap. +test_sample = images.pop +test_label = labels.pop + +# The following lines create an Eigenfaces model for +# face recognition and train it with the images and +# labels read from the given CSV file. +# This here is a full PCA, if you just want to keep +# 10 principal components (read Eigenfaces), then call +# the factory method like this: +# +# EigenFaces.new(10) +# +# If you want to create a FaceRecognizer with a +# confidence threshold (e.g. 123.0), call it with: +# +# EigenFaces.new(10, 123.0) +# +# If you want to use _all_ Eigenfaces and have a threshold, +# then call the method like this: +# +# EigenFaces.new(0, 123.0) +# +model = EigenFaces.new +model.train(images, labels) + +# The following line predicts the label of a given test image: +predicted_label, predicted_confidence = model.predict(test_sample) + +puts "Predicted class: #{predicted_label} / Actual class: #{test_label}" + +eigenvalues = model.get_mat('eigenvalues') +w = model.get_mat('eigenvectors'); +mean = model.get_mat('mean') + +if output_folder + norm_0_255(mean.reshape(1, images[0].rows)).save("#{output_folder}/mean.png") +else + w1 = GUI::Window.new('Predicted') + w2 = GUI::Window.new('Actual') + w3 = GUI::Window.new('mean') + + w1.show images[predicted_label] + w2.show images[test_label] + w3.show norm_0_255(mean.reshape(1, images[0].rows)) +end + +# Display or save the Eigenfaces: +[w.cols, 10].min.times { |i| + puts "Eigenvalue ##{i} = #{eigenvalues[i][0]}" + ev = w.get_cols(i).clone() + grayscale = norm_0_255(ev.reshape(1, height)) + + # Show the image & apply a Jet colormap for better sensing. + cgrayscale = grayscale.apply_color_map(COLORMAP_JET) + if output_folder + norm_0_255(cgrayscale).save("#{output_folder}/eigenface_#{i}.png") + else + w4 = GUI::Window.new("eigenface_#{i}") + w4.show norm_0_255(cgrayscale) + end +} + +[w.cols, 10].min.step([w.cols, 300].min, 15) { |num_components| + # slice the eigenvectors from the model + evs = w.get_cols(0..num_components) + projection = images[0].reshape(1, 1).subspace_project(evs, mean) + reconstruction = projection.subspace_reconstruct(evs, mean) + + # Normalize the result: + reconstruction = norm_0_255(reconstruction.reshape(1, images[0].rows)) + + # Display or save: + if output_folder + norm_0_255(reconstruction).save("#{output_folder}/eigenface_reconstruction_#{num_components}.png") + else + w5 = GUI::Window.new("eigenface_reconstruction_#{num_components}") + w5.show norm_0_255(reconstruction) + end +} + +GUI::wait_key unless output_folder + diff --git a/examples/facerec/facerec_fisherfaces.rb b/examples/facerec/facerec_fisherfaces.rb new file mode 100755 index 00000000..f2f9a4ae --- /dev/null +++ b/examples/facerec/facerec_fisherfaces.rb @@ -0,0 +1,131 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- + +# Fisherfaces sample in ruby-opencv, equivalent to http://docs.opencv.org/trunk/_downloads/facerec_fisherfaces.cpp +# See http://docs.opencv.org/trunk/modules/contrib/doc/facerec/facerec_tutorial.html +require 'opencv' +include OpenCV + +def norm_0_255(src) + dst = nil + case src.channel + when 1 + dst = src.normalize(0, 255, CV_NORM_MINMAX, CV_8UC1) + when 2 + dst = src.normalize(0, 255, CV_NORM_MINMAX, CV_8UC3) + else + dst = src.copy + end + + dst +end + +def read_csv(filename, sepalator = ';') + images = [] + labels = [] + open(filename, 'r') { |f| + f.each { |line| + path, label = line.chomp.split(sepalator) + images << CvMat.load(path, CV_LOAD_IMAGE_GRAYSCALE) + labels << label.to_i + } + } + + [images, labels] +end + +if ARGV.size < 1 + puts "usage: ruby #{__FILE__} " + exit 1 +end +fn_csv = ARGV.shift +output_folder = ARGV.shift + +images, labels = read_csv(fn_csv); + +height = images[0].rows; + +# The following lines simply get the last images from your dataset and remove it +# from the vector. This is done, so that the training data (which we learn the +# cv::FaceRecognizer on) and the test data we test the model with, do not overlap. +test_sample = images.pop +test_label = labels.pop + +# The following lines create an Fisherfaces model for +# face recognition and train it with the images and +# labels read from the given CSV file. +# If you just want to keep 10 Fisherfaces, then call +# the factory method like this: +# +# FisherFaces.new(10) +# +# However it is not useful to discard Fisherfaces! Please +# always try to use _all_ available Fisherfaces for +# classification. +# +# If you want to create a FaceRecognizer with a +# confidence threshold (e.g. 123.0) and use _all_ +# Fisherfaces, then call it with: +# +# FisherFaces.new(0, 123.0); +# +model = FisherFaces.new +model.train(images, labels) + +# The following line predicts the label of a given test image: +predicted_label, predicted_confidence = model.predict(test_sample) + +puts "Predicted class: #{predicted_label} / Actual class: #{test_label}" + +eigenvalues = model.get_mat('eigenvalues') +w = model.get_mat('eigenvectors'); +mean = model.get_mat('mean') + +if output_folder + norm_0_255(mean.reshape(1, images[0].rows)).save("#{output_folder}/mean.png") +else + w1 = GUI::Window.new('Predicted') + w2 = GUI::Window.new('Actual') + w3 = GUI::Window.new('mean') + + w1.show images[predicted_label] + w2.show images[test_label] + w3.show norm_0_255(mean.reshape(1, images[0].rows)) +end + +# Display or save the first, at most 16 Fisherfaces +[w.cols, 16].min.times { |i| + puts "Eigenvalue ##{i} = #{eigenvalues[i][0]}" + ev = w.get_cols(i).clone() + grayscale = norm_0_255(ev.reshape(1, height)) + + # Show the image & apply a Bone colormap for better sensing. + cgrayscale = grayscale.apply_color_map(COLORMAP_BONE) + if output_folder + norm_0_255(cgrayscale).save("#{output_folder}/fisherface_#{i}.png") + else + w4 = GUI::Window.new("fisherface_#{i}") + w4.show norm_0_255(cgrayscale) + end +} + +[w.cols, 16].min.times { |num_component| + # Slice the Fisherface from the model + ev = w.get_cols(num_component) + projection = images[0].reshape(1, 1).subspace_project(ev, mean) + reconstruction = projection.subspace_reconstruct(ev, mean) + + # Normalize the result: + reconstruction = norm_0_255(reconstruction.reshape(1, images[0].rows)) + + # Display or save: + if output_folder + norm_0_255(reconstruction).save("#{output_folder}/fisherface_reconstruction_#{num_component}.png") + else + w5 = GUI::Window.new("fisherface_reconstruction_#{num_component}") + w5.show norm_0_255(reconstruction) + end +} + +GUI::wait_key unless output_folder + diff --git a/examples/facerec/facerec_lbph.rb b/examples/facerec/facerec_lbph.rb new file mode 100755 index 00000000..ba3e8a82 --- /dev/null +++ b/examples/facerec/facerec_lbph.rb @@ -0,0 +1,116 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- + +# LBPH sample in ruby-opencv, equivalent to http://docs.opencv.org/trunk/_downloads/facerec_lbph.cpp +# See http://docs.opencv.org/trunk/modules/contrib/doc/facerec/facerec_tutorial.html +require 'opencv' +include OpenCV + +def read_csv(filename, sepalator = ';') + images = [] + labels = [] + open(filename, 'r') { |f| + f.each { |line| + path, label = line.chomp.split(sepalator) + images << CvMat.load(path, CV_LOAD_IMAGE_GRAYSCALE) + labels << label.to_i + } + } + + [images, labels] +end + +# Check for valid command line arguments, print usage +# if no arguments were given. +if ARGV.size < 1 + puts "usage: ruby #{__FILE__} " + exit 1 +end + +# Get the path to your CSV. +fn_csv = ARGV.shift + +# Read in the data. This can fail if no valid +# input filename is given. +images, labels = read_csv(fn_csv); + +# Quit if there are not enough images for this demo. +raise 'This demo needs at least 2 images to work. Please add more images to your data set!' if images.size <= 1 + +# Get the height from the first image. We'll need this +# later in code to reshape the images to their original size: +height = images[0].rows; + +# The following lines simply get the last images from +# your dataset and remove it from the vector. This is +# done, so that the training data (which we learn the +# cv::FaceRecognizer on) and the test data we test +# the model with, do not overlap. +test_sample = images.pop +test_label = labels.pop + +# The following lines create an LBPH model for +# face recognition and train it with the images and +# labels read from the given CSV file. +# +# The LBPHFaceRecognizer uses Extended Local Binary Patterns +# (it's probably configurable with other operators at a later +# point), and has the following default values +# +# radius = 1 +# neighbors = 8 +# grid_x = 8 +# grid_y = 8 +# +# So if you want a LBPH FaceRecognizer using a radius of +# 2 and 16 neighbors, call the factory method with: +# +# LBPH.new(2, 16); +# +# And if you want a threshold (e.g. 123.0) call it with its default values: +# +# LBPH.new(1,8,8,8,123.0) +# +model = LBPH.new +model.train(images, labels) + +# The following line predicts the label of a given test image: +predicted_label, predicted_confidence = model.predict(test_sample) + +# To get the confidence of a prediction call the model with: +# +# predicted_label = -1; +# confidence = 0.0; +# model.predict(test_sample, predicted_label, confidence) +# +puts "Predicted class: #{predicted_label} / Actual class: #{test_label}" + +# Sometimes you'll need to get/set internal model data, +# which isn't exposed by the public FaceRecognizer. +# Since each FaceRecognizer is derived from a Algorithm, +# you can query the data. +# +# First we'll use it to set the threshold of the FaceRecognizer +# to 0.0 without retraining the model. This can be useful if +# you are evaluating the model: +model.set_double('threshold', 0.0); + +# Now the threshold of this model is set to 0.0. A prediction +# now returns -1, as it's impossible to have a distance below it +predicted_label, predicted_confidence = model.predict(test_sample) +puts "Predicted class = #{predicted_label}" + +# Show some informations about the model, as there's no cool +# Model data to display as in Eigenfaces/Fisherfaces. +# Due to efficiency reasons the LBP images are not stored +# within the model: +puts 'Model Information:' +model_info = "\tLBPH(radius=#{model.get_int('radius')}, neighbors=#{model.get_int('neighbors')}, grid_x=#{model.get_int('grid_x')}, grid_y=#{model.get_int('grid_y')}, threshold=#{model.get_double('threshold')})" +puts model_info + +# We could get the histograms for example: +histgrams = model.get_matvector('histograms'); + +# But should I really visualize it? Probably the length is interesting: +puts "Size of the histograms: #{histgrams[0].dims.reduce(&:*)}" + diff --git a/examples/facerec/readme.md b/examples/facerec/readme.md new file mode 100644 index 00000000..ffaaf4c2 --- /dev/null +++ b/examples/facerec/readme.md @@ -0,0 +1,111 @@ +# Face recognition with ruby-opencv + +This is a face recognition sample with ruby-opencv, which equivalent to the following OpenCV's tutorial. + +[Face Recognition with OpenCV](http://docs.opencv.org/trunk/modules/contrib/doc/facerec/facerec_tutorial.html) + + +## Running samples + +### 1. Get AT&T Facedatabase + +Get AT&T Facedatabase from http://www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html and unzip it. + +```sh +$ wget http://www.cl.cam.ac.uk/Research/DTG/attarchive/pub/data/att_faces.zip +$ unzip att_faces.zip +``` + +### 2. Prepare the data + +Create a CSV file to run samples. + +```sh +$ ruby create_csv.rb att_faces > at.txt +``` + +You will get a CSV file which contains lines composed of a filename followed by a ; followed by the label (as integer number). + +```sh +$ cat at.txt +att_faces/s34/2.pgm;0 +att_faces/s34/3.pgm;0 +att_faces/s34/8.pgm;0 +att_faces/s34/4.pgm;0 +att_faces/s34/5.pgm;0 +att_faces/s34/10.pgm;0 +att_faces/s34/9.pgm;0 +att_faces/s34/7.pgm;0 +att_faces/s34/6.pgm;0 +att_faces/s34/1.pgm;0 +... +``` + +### 3. Run sample codes + +#### Eigenfaces + +```sh +$ mkdir output-eigenfaces +$ ruby facerec_eigenfaces.rb at.txt output-eigenfaces +``` + +You will get the predicted class, actual class and eignvalues shown in console. + +```sh +Predicted class: 39 / Actual class: 39 +Eigenvalue #0 = 2823424.500638128 +Eigenvalue #1 = 2062015.3818895558 +Eigenvalue #2 = 1090171.0771557507 +Eigenvalue #3 = 892019.3644237233 +Eigenvalue #4 = 818537.7917991373 +Eigenvalue #5 = 539058.2364753223 +Eigenvalue #6 = 390359.3231975121 +Eigenvalue #7 = 373809.5486713626 +Eigenvalue #8 = 314658.94374918053 +Eigenvalue #9 = 288764.63018440653 +``` + +The result images will be stored in **output-eigenfaces** . + + +#### Fisherfaces + +```sh +$ mkdir output-fisherfaces +$ ruby facerec_fisherfaces.rb at.txt output-fisherfaces +``` + +You will get the predicted class, actual class and eignvalues like Eigenfaces sample. + +The result images will be stored in **output-fisherfaces** . + + +#### Local Binary Patterns Histograms + +```sh +$ ruby facerec_lbph.rb at.txt +``` + +You will get the predicted class, actual class, model information and size of the histgrams. + +``` +Predicted class: 39 / Actual class: 39 +Predicted class = -1 +Model Information: + LBPH(radius=1, neighbors=8, grid_x=8, grid_y=8, threshold=0.0) +Size of the histograms: 16384 +``` + +## Credits + +### The Database of Faces + +The Database of Faces, formerly The ORL Database of Faces, contains a set of face images taken between April 1992 and April 1994. The database was used in the context of a face recognition project carried out in collaboration with the Speech, Vision and Robotics Group of the Cambridge University Engineering Department. + +There are ten different images of each of 40 distinct subjects. For some subjects, the images were taken at different times, varying the lighting, facial expressions (open / closed eyes, smiling / not smiling) and facial details (glasses / no glasses). All the images were taken against a dark homogeneous background with the subjects in an upright, frontal position (with tolerance for some side movement). + +The files are in PGM format. The size of each image is 92x112 pixels, with 256 grey levels per pixel. The images are organised in 40 directories (one for each subject), which have names of the form sX, where X indicates the subject number (between 1 and 40). In each of these directories, there are ten different images of that subject, which have names of the form Y.pgm, where Y is the image number for that subject (between 1 and 10). + +A copy of the database can be retrieved from: http://www.cl.cam.ac.uk/research/dtg/attarchive/pub/data/att_faces.zip. + diff --git a/examples/find_obj.rb b/examples/find_obj.rb new file mode 100755 index 00000000..ac8f8a69 --- /dev/null +++ b/examples/find_obj.rb @@ -0,0 +1,169 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- + +# A Demo Ruby/OpenCV Implementation of SURF +# See https://code.ros.org/trac/opencv/browser/tags/2.3.1/opencv/samples/c/find_obj.cpp +require 'opencv' +require 'benchmark' +include OpenCV + +def compare_surf_descriptors(d1, d2, best, length) + raise ArgumentError unless (length % 4) == 0 + total_cost = 0 + 0.step(length - 1, 4) { |i| + t0 = d1[i] - d2[i] + t1 = d1[i + 1] - d2[i + 1] + t2 = d1[i + 2] - d2[i + 2] + t3 = d1[i + 3] - d2[i + 3] + total_cost += t0 * t0 + t1 * t1 + t2 * t2 + t3 * t3 + break if total_cost > best + } + total_cost +end + +def naive_nearest_neighbor(vec, laplacian, model_keypoints, model_descriptors) + length = model_descriptors[0].size + neighbor = nil + dist1 = 1e6 + dist2 = 1e6 + + model_descriptors.size.times { |i| + kp = model_keypoints[i] + mvec = model_descriptors[i] + next if laplacian != kp.laplacian + + d = compare_surf_descriptors(vec, mvec, dist2, length) + if d < dist1 + dist2 = dist1 + dist1 = d + neighbor = i + elsif d < dist2 + dist2 = d + end + } + + return (dist1 < 0.6 * dist2) ? neighbor : nil +end + +def find_pairs(object_keypoints, object_descriptors, + image_keypoints, image_descriptors) + ptpairs = [] + object_descriptors.size.times { |i| + kp = object_keypoints[i] + descriptor = object_descriptors[i] + nearest_neighbor = naive_nearest_neighbor(descriptor, kp.laplacian, image_keypoints, image_descriptors) + unless nearest_neighbor.nil? + ptpairs << i + ptpairs << nearest_neighbor + end + } + ptpairs +end + +def locate_planar_object(object_keypoints, object_descriptors, + image_keypoints, image_descriptors, src_corners) + ptpairs = find_pairs(object_keypoints, object_descriptors, image_keypoints, image_descriptors) + n = ptpairs.size / 2 + return nil if n < 4 + + pt1 = [] + pt2 = [] + n.times { |i| + pt1 << object_keypoints[ptpairs[i * 2]].pt + pt2 << image_keypoints[ptpairs[i * 2 + 1]].pt + } + + _pt1 = CvMat.new(1, n, CV_32F, 2) + _pt2 = CvMat.new(1, n, CV_32F, 2) + _pt1.set_data(pt1) + _pt2.set_data(pt2) + h = CvMat.find_homography(_pt1, _pt2, :ransac, 5) + + dst_corners = [] + 4.times { |i| + x = src_corners[i].x + y = src_corners[i].y + z = 1.0 / (h[6][0] * x + h[7][0] * y + h[8][0]) + x = (h[0][0] * x + h[1][0] * y + h[2][0]) * z + y = (h[3][0] * x + h[4][0] * y + h[5][0]) * z + dst_corners << CvPoint.new(x.to_i, y.to_i) + } + + dst_corners +end + + +##### Main ##### +puts 'This program demonstrated the use of the SURF Detector and Descriptor using' +puts 'brute force matching on planar objects.' +puts 'Usage:' +puts "ruby #{__FILE__} , default is box.png and box_in_scene.png" +puts + +object_filename = (ARGV.size == 2) ? ARGV[0] : 'images/box.png' +scene_filename = (ARGV.size == 2) ? ARGV[1] : 'images/box_in_scene.png' + +object, image = nil, nil +begin + object = IplImage.load(object_filename, CV_LOAD_IMAGE_GRAYSCALE) + image = IplImage.load(scene_filename, CV_LOAD_IMAGE_GRAYSCALE) +rescue + puts "Can not load #{object_filename} and/or #{scene_filename}" + puts "Usage: ruby #{__FILE__} [ ]" + exit +end +object_color = object.GRAY2BGR + +param = CvSURFParams.new(1500) + +object_keypoints, object_descriptors = nil, nil +image_keypoints, image_descriptors = nil, nil +tms = Benchmark.measure { + object_keypoints, object_descriptors = object.extract_surf(param) + puts "Object Descriptors: #{object_descriptors.size}" + + image_keypoints, image_descriptors = image.extract_surf(param) + puts "Image Descriptors: #{image_descriptors.size}" +} +puts "Extraction time = #{tms.real * 1000} ms" + +correspond = IplImage.new(image.width, object.height + image.height, CV_8U, 1); +correspond.set_roi(CvRect.new(0, 0, object.width, object.height)) +object.copy(correspond) +correspond.set_roi(CvRect.new(0, object.height, image.width, image.height)) +image.copy(correspond) +correspond.reset_roi + +src_corners = [CvPoint.new(0, 0), CvPoint.new(object.width, 0), + CvPoint.new(object.width, object.height), CvPoint.new(0, object.height)] +dst_corners = locate_planar_object(object_keypoints, object_descriptors, + image_keypoints, image_descriptors, src_corners) + +correspond = correspond.GRAY2BGR +if dst_corners + 4.times { |i| + r1 = dst_corners[i % 4] + r2 = dst_corners[(i + 1) % 4] + correspond.line!(CvPoint.new(r1.x, r1.y + object.height), CvPoint.new(r2.x, r2.y + object.height), + :color => CvColor::Red, :thickness => 2, :line_type => :aa) + } +end + +ptpairs = find_pairs(object_keypoints, object_descriptors, image_keypoints, image_descriptors) + +0.step(ptpairs.size - 1, 2) { |i| + r1 = object_keypoints[ptpairs[i]] + r2 = image_keypoints[ptpairs[i + 1]] + correspond.line!(r1.pt, CvPoint.new(r2.pt.x, r2.pt.y + object.height), + :color => CvColor::Red, :line_type => :aa) +} + +object_keypoints.each { |r| + radius = (r.size * 1.2 / 9.0 * 2).to_i + object_color.circle!(r.pt, radius, :color => CvColor::Red, :line_type => :aa) +} + +GUI::Window.new('Object Correspond').show correspond +GUI::Window.new('Object').show object_color +GUI::wait_key + diff --git a/examples/houghcircle.rb b/examples/houghcircle.rb index c228a4e0..226377fd 100755 --- a/examples/houghcircle.rb +++ b/examples/houghcircle.rb @@ -1,19 +1,18 @@ #!/usr/bin/env ruby # houghcircle.rb require "rubygems" -gem "opencv" require "opencv" include OpenCV original_window = GUI::Window.new "original" hough_window = GUI::Window.new "hough circles" -image = IplImage::load "stuff.jpg" +image = IplImage::load "images/stuff.jpg" gray = image.BGR2GRAY result = image.clone original_window.show image -detect = gray.hough_circles_gradient(2.0, 10, 200, 50) +detect = gray.hough_circles(CV_HOUGH_GRADIENT, 2.0, 10, 200, 50) puts detect.size detect.each{|circle| puts "#{circle.center.x},#{circle.center.y} - #{circle.radius}" diff --git a/examples/images/box.png b/examples/images/box.png new file mode 100644 index 00000000..6f01082f Binary files /dev/null and b/examples/images/box.png differ diff --git a/examples/images/box_in_scene.png b/examples/images/box_in_scene.png new file mode 100644 index 00000000..cff246a3 Binary files /dev/null and b/examples/images/box_in_scene.png differ diff --git a/examples/inpaint.png b/examples/images/inpaint.png similarity index 100% rename from examples/inpaint.png rename to examples/images/inpaint.png diff --git a/examples/images/lena-256x256.jpg b/examples/images/lena-256x256.jpg new file mode 100644 index 00000000..349f8e9d Binary files /dev/null and b/examples/images/lena-256x256.jpg differ diff --git a/examples/images/lena-eyes.jpg b/examples/images/lena-eyes.jpg new file mode 100644 index 00000000..e3f2caa7 Binary files /dev/null and b/examples/images/lena-eyes.jpg differ diff --git a/examples/images/lenna-rotated.jpg b/examples/images/lenna-rotated.jpg new file mode 100644 index 00000000..653a8f39 Binary files /dev/null and b/examples/images/lenna-rotated.jpg differ diff --git a/examples/images/lenna.jpg b/examples/images/lenna.jpg new file mode 100644 index 00000000..f06aa74a Binary files /dev/null and b/examples/images/lenna.jpg differ diff --git a/examples/stuff.jpg b/examples/images/stuff.jpg similarity index 100% rename from examples/stuff.jpg rename to examples/images/stuff.jpg diff --git a/examples/images/tiffany.jpg b/examples/images/tiffany.jpg new file mode 100644 index 00000000..03230e5e Binary files /dev/null and b/examples/images/tiffany.jpg differ diff --git a/examples/inpaint.rb b/examples/inpaint.rb index d0979ac4..de7823bf 100755 --- a/examples/inpaint.rb +++ b/examples/inpaint.rb @@ -1,43 +1,57 @@ #!/usr/bin/env ruby # inpaint.rb require "rubygems" -gem "opencv" require "opencv" - include OpenCV -owindow = GUI::Window.new "original" -mwindow = GUI::Window.new "mask" -iwindow = GUI::Window.new "inpaint" +puts < img2.rows) ? img1.rows : img2.rows +correspond = IplImage.new(width, height, :cv8u, 1); +correspond.set_roi(CvRect.new(0, 0, img1.cols, img1.rows)) +img1.copy(correspond) +correspond.set_roi(CvRect.new(img1.cols, 0, img1.cols + img2.cols, img2.rows)) +img2.copy(correspond) +correspond.reset_roi + +points1.zip(points2) { |pt1, pt2| + pt2.x += img1.cols + correspond.line!(pt1, pt2, :color => CvColor::White) +} + +GUI::Window.new('Object Correspond').show correspond +GUI::wait_key + diff --git a/examples/match_template.rb b/examples/match_template.rb new file mode 100755 index 00000000..f08f2c8a --- /dev/null +++ b/examples/match_template.rb @@ -0,0 +1,26 @@ +#!/usr/bin/env ruby + +# A demo of Ruby/OpenCV's match_template function + +require 'opencv' +include OpenCV + +puts 'This program demonstrates the match_template function' +puts 'Usage:' +puts "ruby #{__FILE__} " +puts + +template_filename = (ARGV.size == 2) ? ARGV[0] : File.expand_path(File.dirname(__FILE__) + '/images/lena-eyes.jpg') +match_image_filename = (ARGV.size == 2) ? ARGV[1] : File.expand_path(File.dirname(__FILE__) + '/images/lena-256x256.jpg') + +template = CvMat.load(template_filename) +match_image = CvMat.load(match_image_filename) +result = match_image.match_template(template, :sqdiff_normed) + +pt1 = result.min_max_loc[2] # minimum location +pt2 = CvPoint.new(pt1.x + template.width, pt1.y + template.height) +match_image.rectangle!(pt1, pt2, :color => CvColor::Black, :thickness => 3) + +window = GUI::Window.new('Display window') # Create a window for display. +window.show(match_image) # Show our image inside it. +GUI::wait_key # Wait for a keystroke in the window. diff --git a/examples/paint.rb b/examples/paint.rb index 82602051..ef7c4667 100755 --- a/examples/paint.rb +++ b/examples/paint.rb @@ -1,16 +1,15 @@ #!/usr/bin/env ruby # paint.rb require "rubygems" -gem "opencv" require "opencv" include OpenCV window = GUI::Window.new("free canvas") -canvas = CvMat.new(500, 500, 0, 3).fill!(0xFF) # create white canvas +canvas = CvMat.new(500, 500, CV_8U, 3).fill!(CvColor::White) # create white canvas window.show canvas -colors = CvColor::constants.collect{|i| i.to_s } +colors = CvColor::constants.collect{ |i| i.to_s } usage =< CvColor::Black, :tickness => 1 } -window.on_mouse{|m| +point = nil +window.on_mouse{ |m| case m.event when :move if m.left_button? @@ -51,22 +49,22 @@ color_name = '' while key = GUI.wait_key - next if key < 0 + next if key < 0 or key > 255 case key.chr when "\e" # [esc] - exit exit when '1'..'9' puts "change thickness to #{key.chr.to_i}." opt[:thickness] = key.chr.to_i - else + when /[A-Za-z]/ color_name << key.chr - choice = colors.find_all{|i| i =~ /\A#{color_name}/i} + choice = colors.find_all{ |i| i =~ /\A#{color_name}/i } if choice.size == 1 color,= choice puts "change color to #{color}." opt[:color] = CvColor::const_get(color) end - color_name = '' if choice.length < 2 + color_name = '' if choice.size < 2 end end diff --git a/examples/snake.rb b/examples/snake.rb index 4c357768..a00d5013 100755 --- a/examples/snake.rb +++ b/examples/snake.rb @@ -1,19 +1,18 @@ #!/usr/bin/env ruby # snake.rb require "rubygems" -gem "opencv" require "opencv" include OpenCV puts < CvColor::White, :thickness => -1) +image.circle!(CvPoint.new(128,128), 40, :color => CvColor::White, :thickness => -1) display = image.GRAY2BGR window.show display @@ -23,7 +22,7 @@ window.on_mouse{|mouse| case mouse.event when :left_button_down - display[mouse.x, mouse.y] = CvColor::Red + display.circle!(mouse, 1, :color => CvColor::Red, :thickness => 2) puts "set point (#{mouse.x},#{mouse.y})" points << CvPoint.new(mouse.x, mouse.y) window.show display @@ -32,10 +31,11 @@ puts "please set more point!" next end - points = image.snake_image(points, 1.0, 0.5, 1.5, CvSize.new(3, 3), 100) + snake_points = image.snake_image(points, 1.0, 0.5, 1.5, CvSize.new(3, 3), 100) display = image.GRAY2BGR - display.poly_line! points, :color => CvColor::Red, :is_closed => true + display.poly_line!([snake_points], :color => CvColor::Red, :is_closed => true, :thickness => 2) window.show display + points.clear end } diff --git a/ext/curve.cpp b/ext/curve.cpp deleted file mode 100644 index 2bf2d870..00000000 --- a/ext/curve.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/************************************************************ - - curve.cpp - - - $Author: lsxi $ - - Copyright (C) 2005 Masakazu Yonekura - -************************************************************/ -#include"curve.h" -/* - * Document-class: OpenCV::Curve - * - * Curve sequence. - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CURVE - -VALUE module; - -VALUE -rb_module() -{ - return module; -} - -void -define_ruby_module() -{ - if(module) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - module = rb_define_module_under(opencv, "Curve"); - rb_define_method(module, "close?", RUBY_METHOD_FUNC(rb_closed_q), 0); - rb_define_method(module, "convex?", RUBY_METHOD_FUNC(rb_convex_q), 0); - rb_define_method(module, "hole?", RUBY_METHOD_FUNC(rb_hole_q), 0); - rb_define_method(module, "simple?", RUBY_METHOD_FUNC(rb_simple_q), 0); - rb_define_method(module, "arc_length", RUBY_METHOD_FUNC(rb_arc_length), -1); -} - -/* - * If curve is closed, return true. Otherwise return false. - */ -VALUE -rb_closed_q(VALUE self) -{ - return CV_IS_SEQ_CLOSED(CVSEQ(self)) ? Qtrue : Qfalse; -} - -/* - * If curve is convex, return true. Otherwise return false. - */ -VALUE -rb_convex_q(VALUE self) -{ - return CV_IS_SEQ_CONVEX(CVSEQ(self)) ? Qtrue : Qfalse; -} - -/* - * If curve is hole(inner contour), return true. Otherwise return false. - */ -VALUE -rb_hole_q(VALUE self) -{ - return CV_IS_SEQ_HOLE(CVSEQ(self)) ? Qtrue : Qfalse; -} - -/* - * no idia. - */ -VALUE -rb_simple_q(VALUE self) -{ - return CV_IS_SEQ_SIMPLE(CVSEQ(self)) ? Qtrue : Qfalse; -} - -/* - * call-seq: - * arc_length([slice = nil][,is_closed = nil]) -> float - * - * Calculates contour perimeter or curve length. - * slice is starting and ending points of the curve. - * is_closed is indicates whether the curve is closed or not. There are 3 cases: - * * is_closed = true - the curve is assumed to be unclosed. - * * is_closed = false - the curve is assumed to be closed. - * * is_closed = nil (default) use self#close? - */ -VALUE -rb_arc_length(int argc, VALUE *argv, VALUE self) -{ - VALUE slice, is_closed; - rb_scan_args(argc, argv, "02", &slice, &is_closed); - return rb_float_new(cvArcLength(CVARR(self), NIL_P(slice) ? CV_WHOLE_SEQ : VALUE_TO_CVSLICE(slice), TRUE_OR_FALSE(is_closed, -1))); -} - -__NAMESPACE_END_CURVE -__NAMESPACE_END_OPENCV - diff --git a/ext/cvbox2d.cpp b/ext/cvbox2d.cpp deleted file mode 100644 index 1b07b9a5..00000000 --- a/ext/cvbox2d.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/************************************************************ - - cvbox2d.cpp - - - $Author: lsxi $ - - Copyright (C) 2005-2006 Masakazu Yonekura - -************************************************************/ -#include "cvbox2d.h" -/* - * Document-class: OpenCV::CvBox2D - * - * C structure is here. - * typdef struct CvBox2D{ - * CvPoint2D32f center; // center of the box. - * CvSize2D32f size; // box width and length - * float angle; // angle between the horizonal axis and the first side (i.e length) in radians - * }CvBox2D; - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVBOX2D - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void -define_ruby_class() -{ - if(rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - rb_klass = rb_define_class_under(opencv, "CvBox2D", rb_cObject); - rb_define_method(rb_klass, "center", RUBY_METHOD_FUNC(rb_center), 0); - rb_define_method(rb_klass, "size", RUBY_METHOD_FUNC(rb_size), 0); - rb_define_method(rb_klass, "angle", RUBY_METHOD_FUNC(rb_angle), 0); - rb_define_method(rb_klass, "points", RUBY_METHOD_FUNC(rb_points), 0); -} - -VALUE -rb_allocate(VALUE klass) -{ - CvBox2D *ptr; - return Data_Make_Struct(klass, CvBox2D, 0, -1, ptr); -} - -/* - * Return center point of box as CvPoint2D32f. - */ -VALUE -rb_center(VALUE self) -{ - return REFER_OBJECT(cCvPoint2D32f::rb_class(), &CVBOX2D(self)->center, self); -} - -/* - * Return size of box as CvSize2D32f. - */ -VALUE -rb_size(VALUE self) -{ - return REFER_OBJECT(cCvSize2D32f::rb_class(), &CVBOX2D(self)->size, self); -} - -/* - * Return angle of box as Float. - */ -VALUE -rb_angle(VALUE self) -{ - return rb_float_new(CVBOX2D(self)->angle); -} - -/* - * Find box vertices. Return Array contain 4 CvPoint2D32f. - */ -VALUE -rb_points(VALUE self) -{ - const int n = 4; - CvPoint2D32f p[n]; - cvBoxPoints(*CVBOX2D(self), p); - VALUE points = rb_ary_new2(n); - for(int i = 0; i < n; i++) - rb_ary_store(points, i, cCvPoint2D32f::new_object(p[i])); - return points; -} - -VALUE -new_object() -{ - return rb_allocate(cCvBox2D::rb_class()); -} - -VALUE -new_object(CvBox2D box) -{ - VALUE object = rb_allocate(rb_klass); - *CVBOX2D(object) = box; - return object; -} - -__NAMESPACE_END_CVBOX2D -__NAMESPACE_END_OPENCV diff --git a/ext/cvcapture.cpp b/ext/cvcapture.cpp deleted file mode 100644 index 840800bf..00000000 --- a/ext/cvcapture.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/************************************************************ - - cvcapture.cpp - - - $Author: lsxi $ - - Copyright (C) 2005-2006 Masakazu Yonekura - -************************************************************/ -#include"cvcapture.h" -/* - * Document-class: OpenCV::CvCapture - * - * Capture image from video stream. - * - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVCAPTURE - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - rb_klass = rb_define_class_under(opencv, "CvCapture", rb_cData); - - VALUE video_interface = rb_hash_new(); - /* {:any, :mil, :vfw, :v4l, :v4l2, :fireware, :ieee1394, :dc1394, :cmu1394, :stereo, :tyzx, :tyzx_left, :tyzx_right, :tyzx_color, :tyzx_z, :qt, :qtuicktime}: video source */ - rb_define_const(rb_klass, "INTERFACE", video_interface); - rb_hash_aset(video_interface, ID2SYM(rb_intern("any")), INT2FIX(CV_CAP_ANY)); - rb_hash_aset(video_interface, ID2SYM(rb_intern("mil")), INT2FIX(CV_CAP_MIL)); - rb_hash_aset(video_interface, ID2SYM(rb_intern("vfw")), INT2FIX(CV_CAP_VFW)); - rb_hash_aset(video_interface, ID2SYM(rb_intern("v4l")), INT2FIX(CV_CAP_V4L)); - rb_hash_aset(video_interface, ID2SYM(rb_intern("v4l2")), INT2FIX(CV_CAP_V4L2)); - rb_hash_aset(video_interface, ID2SYM(rb_intern("fireware")), INT2FIX(CV_CAP_FIREWARE)); - rb_hash_aset(video_interface, ID2SYM(rb_intern("ieee1394")), INT2FIX(CV_CAP_IEEE1394)); - rb_hash_aset(video_interface, ID2SYM(rb_intern("dc1394")), INT2FIX(CV_CAP_DC1394)); - rb_hash_aset(video_interface, ID2SYM(rb_intern("cmu1394")), INT2FIX(CV_CAP_CMU1394)); - rb_hash_aset(video_interface, ID2SYM(rb_intern("stereo")), INT2FIX(CV_CAP_STEREO)); - rb_hash_aset(video_interface, ID2SYM(rb_intern("tyzx")), INT2FIX(CV_CAP_TYZX)); - rb_hash_aset(video_interface, ID2SYM(rb_intern("tyzx_left")), INT2FIX(CV_TYZX_LEFT)); - rb_hash_aset(video_interface, ID2SYM(rb_intern("tyzx_right")), INT2FIX(CV_TYZX_RIGHT)); - rb_hash_aset(video_interface, ID2SYM(rb_intern("tyzx_color")), INT2FIX(CV_TYZX_COLOR)); - rb_hash_aset(video_interface, ID2SYM(rb_intern("tyzx_z")), INT2FIX(CV_TYZX_Z)); - rb_hash_aset(video_interface, ID2SYM(rb_intern("qt")), INT2FIX(CV_CAP_QT)); - rb_hash_aset(video_interface, ID2SYM(rb_intern("quicktime")), INT2FIX(CV_CAP_QT)); - - rb_define_singleton_method(rb_klass, "open", RUBY_METHOD_FUNC(rb_open), -1); - - rb_define_method(rb_klass, "grab", RUBY_METHOD_FUNC(rb_grab), 0); - rb_define_method(rb_klass, "retrieve", RUBY_METHOD_FUNC(rb_retrieve), 0); - rb_define_method(rb_klass, "query", RUBY_METHOD_FUNC(rb_query), 0); - rb_define_method(rb_klass, "millisecond", RUBY_METHOD_FUNC(rb_millisecond), 0); - rb_define_method(rb_klass, "frames", RUBY_METHOD_FUNC(rb_frames), 0); - rb_define_method(rb_klass, "size", RUBY_METHOD_FUNC(rb_size), 0); - rb_define_method(rb_klass, "width", RUBY_METHOD_FUNC(rb_width), 0); - rb_define_method(rb_klass, "height", RUBY_METHOD_FUNC(rb_height), 0); - rb_define_method(rb_klass, "fps", RUBY_METHOD_FUNC(rb_fps), 0); - rb_define_method(rb_klass, "fourcc", RUBY_METHOD_FUNC(rb_fourcc), 0); - rb_define_method(rb_klass, "frame_count", RUBY_METHOD_FUNC(rb_frame_count), 0); -} - -void -free(void *ptr) -{ - if(ptr) - cvReleaseCapture((CvCapture**)&ptr); -} - -/* - * call-seq: - * CvCapture.open([dev = -1]) - * - * Reading video stream from the specified file or camera device. - * If dev is string (i.e "stream.avi"), reading video stream from file. - * If dev is number or symbol(include CvCapture::INTERFACE), - * reading video stream from camera. - * Currently two camera interfaces can be used on Windows: - * * Video for Windows(VFW) - * * Matrox Imaging Library(MIL) - * and two on Linux - * * V4L - * * FireWire(IEEE1394). - * If there is only one camera or it does not matter what camera to use nil may be passed. - */ -VALUE -rb_open(int argc, VALUE *argv, VALUE self) -{ - VALUE device, i; - rb_scan_args(argc, argv, "01", &device); - CvCapture *capture = 0; - switch (TYPE(device)) { - case T_STRING: - capture = cvCaptureFromFile(StringValueCStr(device)); - break; - case T_FIXNUM: - capture = cvCaptureFromCAM(FIX2INT(device)); - break; - case T_SYMBOL: - i = rb_hash_aref(rb_const_get(rb_class(), rb_intern("INTERFACE")), device); - if (NIL_P(i)) - rb_raise(rb_eArgError, "undefined interface."); - capture = cvCaptureFromCAM(NUM2INT(i)); - break; - case T_NIL: - capture = cvCaptureFromCAM(CV_CAP_ANY); - break; - } - if (!capture) - rb_raise(rb_eStandardError, "Invalid capture format."); - return Data_Wrap_Struct(rb_klass, 0, free, capture); -} - - -/* - * call-seq: - * grab -> true or false - * - * Grabbed frame is stored internally. To grab frame - * fast that is important for syncronization in case of reading from - * several cameras simultaneously. The grabbed frames are not exposed because - * they may be stored in compressed format (as defined by camera/driver). - * To retrieve the grabbed frame, retrieve should be used. - * - * If grabbed frame was success, return true. Otherwise return false. - */ -VALUE -rb_grab(VALUE self) -{ - return cvGrabFrame(CVCAPTURE(self)) ? Qtrue : Qfalse; -} - -/* - * call-seq: - * retrieve -> CvMat or nil - * - * Gets the image grabbed with grab. - */ -VALUE -rb_retrieve(VALUE self) -{ - IplImage *frame = cvRetrieveFrame(CVCAPTURE(self)); - if(!frame) - return Qnil; - VALUE image = cIplImage::new_object(cvSize(frame->width, frame->height), CV_MAKETYPE(CV_8U, frame->nChannels)); - if (frame->origin == IPL_ORIGIN_TL) { - cvCopy(frame, CVARR(image)); - } else { - cvFlip(frame, CVARR(image)); - } - return image; -} - -/* - * call-seq: - * query -> CvMat or nil - * - * Grabs and returns a frame camera or file. Just a combination of grab and retrieve in one call. - */ -VALUE -rb_query(VALUE self) -{ - IplImage *frame = cvQueryFrame(CVCAPTURE(self)); - if(!frame) - return Qnil; - VALUE image = cIplImage::new_object(cvSize(frame->width, frame->height), CV_MAKETYPE(CV_8U, frame->nChannels)); - if (frame->origin == IPL_ORIGIN_TL) { - cvCopy(frame, CVARR(image)); - } else { - cvFlip(frame, CVARR(image)); - } - return image; -} - -/* - * Film current position in milliseconds or video capture timestamp. - */ -VALUE -rb_millisecond(VALUE self) -{ - return rb_dbl2big(cvGetCaptureProperty(CVCAPTURE(self), CV_CAP_PROP_POS_MSEC)); -} - -/* - * 0-based index of the frame to be decoded/captured next - */ -VALUE -rb_frames(VALUE self) -{ - return rb_float_new(cvGetCaptureProperty(CVCAPTURE(self), CV_CAP_PROP_POS_FRAMES)); -} - -/* - * Relative position of video file (0 - start of the film, 1 - end of the film) - */ -VALUE -rb_avi_ratio(VALUE self) -{ - return rb_float_new(cvGetCaptureProperty(CVCAPTURE(self), CV_CAP_PROP_POS_AVI_RATIO)); -} - -/* - * Size of frames in the video stream. - */ -VALUE -rb_size(VALUE self) -{ - return cCvSize::new_object(cvSize((int)cvGetCaptureProperty(CVCAPTURE(self), CV_CAP_PROP_FRAME_WIDTH), (int)cvGetCaptureProperty(CVCAPTURE(self), CV_CAP_PROP_FRAME_HEIGHT))); -} - -/* - * Width of frames in the video stream. - */ -VALUE -rb_width(VALUE self) -{ - return rb_dbl2big(cvGetCaptureProperty(CVCAPTURE(self), CV_CAP_PROP_FRAME_WIDTH)); -} - -/* - * Height of frames in the video stream. - */ -VALUE -rb_height(VALUE self) -{ - return rb_dbl2big(cvGetCaptureProperty(CVCAPTURE(self), CV_CAP_PROP_FRAME_HEIGHT)); -} - -/* - * Frame rate - */ -VALUE -rb_fps(VALUE self) -{ - return rb_dbl2big(cvGetCaptureProperty(CVCAPTURE(self), CV_CAP_PROP_FPS)); -} - -/* - * 4character code of codec. see http://www.fourcc.org/ - */ -VALUE -rb_fourcc(VALUE self) -{ - char str[4]; - double fourcc = cvGetCaptureProperty(CVCAPTURE(self), CV_CAP_PROP_FOURCC); - sprintf(str, "%s", (char*)&fourcc); - return rb_str_new2(str); -} - -/* - * Number of frames in video file. - */ -VALUE -rb_frame_count(VALUE self) -{ - return rb_dbl2big(cvGetCaptureProperty(CVCAPTURE(self), CV_CAP_PROP_FRAME_COUNT)); -} - - -__NAMESPACE_END_CVCAPTURE -__NAMESPACE_END_OPENCV diff --git a/ext/cvcapture.h b/ext/cvcapture.h deleted file mode 100644 index 13638528..00000000 --- a/ext/cvcapture.h +++ /dev/null @@ -1,54 +0,0 @@ -/************************************************************ - - cvcapture.h - - - $Author: lsxi $ - - Copyright (C) 2005-2006 Masakazu Yonekura - -************************************************************/ -#ifndef RUBY_OPENCV_CVCAPTURE_H -#define RUBY_OPENCV_CVCAPTURE_H - -#include "opencv.h" - -#define __NAMESPACE_BEGIN_CVCAPTURE namespace cCvCapture{ -#define __NAMESPACE_END_CVCAPTURE } - -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVCAPTURE - - -VALUE rb_class(); - -void define_ruby_class(); - -void free(void *ptr); -VALUE rb_open(int argc, VALUE *argv, VALUE klass); - -VALUE rb_grab(VALUE self); -VALUE rb_retrieve(VALUE self); -VALUE rb_query(VALUE self); - -VALUE rb_millisecond(VALUE self); -VALUE rb_frames(VALUE self); -VALUE rb_avi_ratio(VALUE self); -VALUE rb_size(VALUE self); -VALUE rb_width(VALUE self); -VALUE rb_height(VALUE self); -VALUE rb_fps(VALUE self); -VALUE rb_fourcc(VALUE self); -VALUE rb_frame_count(VALUE self); - -__NAMESPACE_END_CVCAPTURE - - -inline CvCapture *CVCAPTURE(VALUE object){ - CvCapture *ptr; - Data_Get_Struct(object, CvCapture, ptr); - return ptr; -} - -__NAMESPACE_END_OPENCV - -#endif // RUBY_OPENCV_CVCAPTURE_H diff --git a/ext/cvchain.cpp b/ext/cvchain.cpp deleted file mode 100644 index 8058dd91..00000000 --- a/ext/cvchain.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/************************************************************ - - cvchain.cpp - - - $Author: lsxi $ - - Copyright (C) 2007 Masakazu Yonekura - -************************************************************/ -#include "cvchain.h" -/* - * Document-class: OpenCV::CvChain - * - * Freeman chain code. - * CvMat#find_contours(:method => :code) - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVCHAIN - -#define APPROX_CHAIN_OPTION(op) NIL_P(op) ? rb_const_get(rb_class(), rb_intern("APPROX_CHAIN_OPTION")) : rb_funcall(rb_const_get(rb_class(), rb_intern("APPROX_CHAIN_OPTION")), rb_intern("merge"), 1, op) -#define APPROX_CHAIN_METHOD(op) CVMETHOD("APPROX_CHAIN_METHOD", rb_hash_aref(op, ID2SYM(rb_intern("method"))), CV_CHAIN_APPROX_SIMPLE) -#define APPROX_CHAIN_PARAMETER(op) NUM2INT(rb_hash_aref(op, ID2SYM(rb_intern("parameter")))) -#define APPROX_CHAIN_MINIMAL_PARAMETER(op) NUM2INT(rb_hash_aref(op, ID2SYM(rb_intern("minimal_parameter")))) -#define APPROX_CHAIN_RECURSIVE(op) ({VALUE _recursive = rb_hash_aref(op, ID2SYM(rb_intern("recursive"))); NIL_P(_recursive) ? 0 : _recursive == Qfalse ? 0 : 1;}) - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * cvseq = rb_define_class_under(opencv, "CvSeq"); - * curve = rb_define_module_under(opencv, "Curve"); - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - VALUE cvseq = cCvSeq::rb_class(); - VALUE curve = mCurve::rb_module(); - - rb_klass = rb_define_class_under(opencv, "CvChain", cvseq); - rb_include_module(rb_klass, curve); - VALUE approx_chain_option = rb_hash_new(); - rb_define_const(rb_klass, "APPROX_CHAIN_OPTION", approx_chain_option); - rb_hash_aset(approx_chain_option, ID2SYM(rb_intern("method")), ID2SYM(rb_intern("approx_simple"))); - rb_hash_aset(approx_chain_option, ID2SYM(rb_intern("parameter")), rb_float_new(0)); - rb_hash_aset(approx_chain_option, ID2SYM(rb_intern("minimal_parameter")), INT2FIX(0)); - rb_hash_aset(approx_chain_option, ID2SYM(rb_intern("recursive")), Qfalse); - - rb_define_method(rb_klass, "origin", RUBY_METHOD_FUNC(rb_origin), 0); - rb_define_method(rb_klass, "origin=", RUBY_METHOD_FUNC(rb_set_origin), 0); - rb_define_method(rb_klass, "codes", RUBY_METHOD_FUNC(rb_codes), 0); - rb_define_method(rb_klass, "points", RUBY_METHOD_FUNC(rb_points), 0); - rb_define_method(rb_klass, "approx_chain", RUBY_METHOD_FUNC(rb_approx_chain), -1); - rb_define_alias(rb_klass, "approx", "approx_chain"); -} - -/* - * call-seq: - * origin -> cvpoint - * - * Return Freeman chain code origin. - */ -VALUE -rb_origin(VALUE self) -{ - return cCvPoint::new_object(CVCHAIN(self)->origin); -} - -/* - * call-seq: - * origin = point -> self - * - * Set Freeman chain code origin. - */ -VALUE -rb_set_origin(VALUE self, VALUE origin) -{ - CVCHAIN(self)->origin = VALUE_TO_CVPOINT(origin); - return self; -} - -/* - * call-seq: - * codes -> array(contain fixnum) - * - * Return Freeman chain codes. - */ -VALUE -rb_codes(VALUE self) -{ - CvChain *chain = CVCHAIN(self); - CvChainPtReader reader; - CvPoint p = chain->origin; - VALUE ary = rb_ary_new2(chain->total); - cvStartReadChainPoints(chain, &reader); - for (int i = 0; i < chain->total; i++) { - CV_READ_SEQ_ELEM(reader.code, (*((CvSeqReader*)&(reader)))); - rb_ary_store(ary, i, CHR2FIX(reader.code)); - } - return ary; -} - -/* - * call-seq: - * points -> array(contain cvpoint) - * - * Return points that represent by Freeman chain code. - */ -VALUE -rb_points(VALUE self) -{ - CvChain *chain = CVCHAIN(self); - CvChainPtReader reader; - CvPoint p = chain->origin; - VALUE ary = rb_ary_new2(chain->total); - cvStartReadChainPoints(chain, &reader); - for (int i = 0; i < chain->total; i++) { - CV_READ_CHAIN_POINT(p, reader); - rb_ary_store(ary, i, cCvPoint::new_object(p)); - } - return ary; -} - -/* - * call-seq: - * approx_chain([approx_chain_option]) -> cvcontour - * - * Approximates Freeman chain(s) with polygonal curve. - * approx_chain_option should be Hash include these keys. - * :method - Approximation method. - * :approx_none - translate all the points from the chain code into points; - * :approx_simple(default) - compress horizontal, vertical, and diagonal segments, that is, - * the function leaves only their ending points. - * :approx_tc89_l1 - * :approx_tc89_kcos - apply one of the flavors of Teh-Chin chain approximation algorithm. - * If set the difference between the current pixel and seed pixel is considered, - * otherwise difference between neighbor pixels is considered (the range is floating). - * :parameter - Method parameter (not used now). - * :minimal_perimeter (default 0) - * Approximates only those contours whose perimeters are not less than minimal_perimeter. Other chains are removed from the resulting structure. - * :recursive (default false) - * If not nil or false, the function approximates all chains that access can be obtained to - * from self by h_next or v_next links. If 0, the single chain is approximated. - * - */ -VALUE -rb_approx_chain(int argc, VALUE *argv, VALUE self) -{ - VALUE approx_chain_option, storage; - rb_scan_args(argc, argv, "01", &approx_chain_option); - approx_chain_option = APPROX_CHAIN_OPTION(approx_chain_option); - /* can't compile VC - storage = cCvMemStorage::new_object(); - CvSeq *seq = cvApproxChains(CVSEQ(self), CVMEMSTORAGE(storage), - APPROX_CHAIN_METHOD(approx_chain_option), - APPROX_CHAIN_PARAMETER(approx_chain_option), - APPROX_CHAIN_MINIMAL_PARAMETER(approx_chain_option), - APPROX_CHAIN_RECURSIVE(approx_chain_option)); - - return cCvSeq::new_sequence(cCvContour::rb_class(), seq, cCvPoint::rb_class(), storage); - */ - return Qnil; -} - -VALUE -new_object() -{ - VALUE storage = cCvMemStorage::new_object(); - CvSeq *seq = cvCreateSeq(CV_SEQ_CHAIN_CONTOUR, sizeof(CvChain), sizeof(CvChainCode), CVMEMSTORAGE(storage)); - VALUE object = cCvSeq::new_sequence(cCvChain::rb_class(), seq, cCvChainCode::rb_class(), storage); - return object; -} - -__NAMESPACE_END_CVCHAIN -__NAMESPACE_END_OPENCV diff --git a/ext/cvchaincode.cpp b/ext/cvchaincode.cpp deleted file mode 100644 index f7e26b98..00000000 --- a/ext/cvchaincode.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/************************************************************ - - cvchaincode.cpp - - - $Author: lsxi $ - - Copyright (C) 2007 Masakazu Yonekura - -************************************************************/ -#include "cvchaincode.h" -/* - * Document-class: OpenCV::CvChainCode - * - * Freeman chain code. - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVCHAINCODE - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - rb_klass = rb_define_class_under(opencv, "CvChainCode", rb_cObject); -} - -VALUE -rb_to_i(VALUE self) -{ - return CHR2FIX(CVCHAINCODE(self)->code); -} - -__NAMESPACE_END_CVCHAINCODE -__NAMESPACE_END_OPENCV diff --git a/ext/cvchaincode.h b/ext/cvchaincode.h deleted file mode 100644 index be326635..00000000 --- a/ext/cvchaincode.h +++ /dev/null @@ -1,43 +0,0 @@ -/************************************************************ - - opchaincode.h - - - $Author: lsxi $ - - Copyright (C) 2008 Masakazu Yonekura - - ************************************************************/ -#ifndef RUBY_OPENCV_CVCHAINCODE_H -#define RUBY_OPENCV_CVCHAINCODE_H - -#include "opencv.h" - -#define __NAMESPACE_BEGIN_CVCHAINCODE namespace cCvChainCode{ -#define __NAMESPACE_END_CVCHAINCODE } - -typedef struct CvChainCode{ - char code; -}CvChainCode; - -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVCHAINCODE - -VALUE rb_class(); - -void define_ruby_class(); - -VALUE rb_to_i(VALUE self); - -__NAMESPACE_END_CVCHAINCODE - -inline CvChainCode* -CVCHAINCODE(VALUE object){ - CvChainCode *ptr; - Data_Get_Struct(object, CvChainCode, ptr); - return ptr; -} - - -__NAMESPACE_END_OPENCV - -#endif // RUBY_OPENCV_CVCHAINCODE_H diff --git a/ext/cvcondensation.cpp b/ext/cvcondensation.cpp deleted file mode 100644 index be74c864..00000000 --- a/ext/cvcondensation.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/************************************************************ - - cvcondensation.cpp - - - $Author: lsxi $ - - Copyright (C) 2005-2006 Masakazu Yonekura - -************************************************************/ -#include "cvcondensation.h" -/* - * Document-class: OpenCV::CvConDensation - * - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVCONDENSATION - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void -define_ruby_class() -{ - if(rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - rb_klass = rb_define_class_under(opencv, "CvConDensation", rb_cObject); - rb_define_method(rb_klass, "dp", RUBY_METHOD_FUNC(rb_dp), 0); - rb_define_method(rb_klass, "mp", RUBY_METHOD_FUNC(rb_mp), 0); - rb_define_method(rb_klass, "dynamic_matrix", RUBY_METHOD_FUNC(rb_dynamic_matrix), 0); - rb_define_method(rb_klass, "confidence", RUBY_METHOD_FUNC(rb_confidence), 0); - rb_define_method(rb_klass, "cumulative", RUBY_METHOD_FUNC(rb_cumulative), 0); - rb_define_method(rb_klass, "state", RUBY_METHOD_FUNC(rb_state), 0); - rb_define_method(rb_klass, "samples_num", RUBY_METHOD_FUNC(rb_samples_num), 0); - rb_define_method(rb_klass, "init_sample_set", RUBY_METHOD_FUNC(rb_init_sample_set), 2); - rb_define_method(rb_klass, "update_by_time", RUBY_METHOD_FUNC(rb_update_by_time), 0); - rb_define_alias(rb_klass, "update", "update_by_time"); - rb_define_method(rb_klass, "each_sample", RUBY_METHOD_FUNC(rb_each_sample), 0); - rb_define_method(rb_klass, "calculate_confidence", RUBY_METHOD_FUNC(rb_calculate_confidence), 0); -} - -/* - * call-seq: - * dp -> int - * - * Return dimension of state vector - */ -VALUE -rb_dp(VALUE self) -{ - return INT2FIX(CVCONDENSATION(self)->DP); -} - -/* - * call-seq: - * mp -> int - * - * Return demension of measurement vector. - */ -VALUE -rb_mp(VALUE self) -{ - return INT2FIX(CVCONDENSATION(self)->MP); -} - -/* - * call-seq: - * dynamic_matrix -> mat - * - * Return matrix of the linear Dynamics system. - */ -VALUE -rb_dynamic_matrix(VALUE self) -{ - CvConDensation *cd = CVCONDENSATION(self); - return DEPEND_OBJECT(cCvMat::rb_class(), cvInitMatHeader(ALLOC(CvMat), cd->DP, cd->DP, CV_MAKETYPE(CV_32F, 1), cd->DynamMatr), self); -} - -/* - * call-seq: - * confidence -> mat - * - * Return confidence for each sample. - */ -VALUE -rb_confidence(VALUE self) -{ - CvConDensation *cd = CVCONDENSATION(self); - return DEPEND_OBJECT(cCvMat::rb_class(), cvInitMatHeader(ALLOC(CvMat), cd->SamplesNum, 1, CV_MAKETYPE(CV_32F, 1), cd->flConfidence), self); -} - -/* - * call-seq: - * cumulative -> mat - * - * Return cumulative confidence. - */ -VALUE -rb_cumulative(VALUE self) -{ - CvConDensation *cd = CVCONDENSATION(self); - return DEPEND_OBJECT(cCvMat::rb_class(), cvInitMatHeader(ALLOC(CvMat), cd->SamplesNum, 1, CV_MAKETYPE(CV_32F, 1), cd->flCumulative), self); -} - -/* - * call-seq: - * state -> mat - * - * Return vector of state - */ -VALUE -rb_state(VALUE self) -{ - CvConDensation *cd = CVCONDENSATION(self); - return DEPEND_OBJECT(cCvMat::rb_class(), cvInitMatHeader(ALLOC(CvMat), cd->DP, 1, CV_MAKETYPE(CV_32F, 1), cd->State), self); -} - -/* - * call-seq: - * samples_num -> int - * - * Return number of the samples - */ -VALUE -rb_samples_num(VALUE self) -{ - return INT2FIX(CVCONDENSATION(self)->SamplesNum); -} - -/* - * call-seq: - * init_sample_set(upper, lower) - * - * Initializes sample set for ConDensation algorithm. - * Fills the samples with values within specified(lower to upper) ranges. - */ -VALUE -rb_init_sample_set(VALUE self, VALUE lower, VALUE upper) -{ - CvConDensation *cd = CVCONDENSATION(self); - CvMat *lower_bound = CVMAT(lower), *upper_bound = CVMAT(upper), lb_stub, ub_stub; - int lower_type = lower_bound->type, upper_type = lower_bound->type; - if (lower_type != CV_32FC1 || lower_bound->cols != 1) { - if (CV_MAT_DEPTH(lower_type) == CV_32F) { - lower_bound = cvReshape(lower_bound, &lb_stub, 1, lower_bound->rows * lower_bound->cols); - } else { - lower = cCvMat::new_object(cvSize(lower_bound->rows * lower_bound->cols, 1), CV_MAKETYPE(CV_32S, 1)); - cvConvertScale(lower_bound, CVARR(lower)); - lower_bound = CVMAT(lower); - } - } - if (upper_type != CV_32FC1 || upper_bound->cols != 1) { - if (CV_MAT_DEPTH(upper_type) == CV_32F) { - upper_bound = cvReshape(upper_bound, &ub_stub, 1, upper_bound->rows * upper_bound->cols); - } else { - upper = cCvMat::new_object(cvSize(upper_bound->rows * upper_bound->cols, 1), CV_MAKETYPE(CV_32F, 1)); - cvConvertScale(upper_bound, CVARR(upper)); - upper_bound = CVMAT(upper); - } - } - if (lower_bound->rows != cd->DP || upper_bound->rows != cd->DP) { - rb_raise(rb_eTypeError, "sample matrix step unmatch."); - } - cvConDensInitSampleSet(cd, lower_bound, upper_bound); - return self; -} - -/* - * call-seq: - * update_by_time - * - * Estimates subsequent model state. - */ -VALUE -rb_update_by_time(VALUE self) -{ - cvConDensUpdateByTime(CVCONDENSATION(self)); - return self; -} - -/* - * call-seq: - * each_sample{|mat| ... } - * - * Evaluate each sample by given block. - */ -VALUE -rb_each_sample(VALUE self) -{ - CvConDensation *cd = CVCONDENSATION(self); - if (rb_block_given_p()) { - for (int i = 0; i < cd->SamplesNum; i++) { - rb_yield(DEPEND_OBJECT(cCvMat::rb_class(), cvInitMatHeader(ALLOC(CvMat), cd->DP, 1, CV_MAKETYPE(CV_32F, 1), cd->flSamples[i]), self)); - } - } - return self; -} - -/* - * call-seq: - * calculate_confidence{|value| ... } - * - * Evalute each sample by given block, then return value set to confidence. - */ -VALUE -rb_calculate_confidence(VALUE self) -{ - VALUE value; - CvConDensation *cd = CVCONDENSATION(self); - if (rb_block_given_p()) { - for (int i = 0; i < cd->SamplesNum; i++) { - value = rb_yield(DEPEND_OBJECT(cCvMat::rb_class(), cvInitMatHeader(ALLOC(CvMat), cd->DP, 1, CV_MAKETYPE(CV_32F, 1), cd->flSamples[i]), self)); - cd->flConfidence[i] = NUM2DBL(value); - } - } - return self; -} - -__NAMESPACE_END_CVCONDENSATION -__NAMESPACE_END_OPENCV diff --git a/ext/cvcondensation.h b/ext/cvcondensation.h deleted file mode 100644 index dd3950e1..00000000 --- a/ext/cvcondensation.h +++ /dev/null @@ -1,49 +0,0 @@ -/************************************************************ - - cvcondensation.h - - - $Author: lsxi $ - - Copyright (C) 2005-2006 Masakazu Yonekura - -************************************************************/ -#ifndef RUBY_OPENCV_CVCONDENSATION_H -#define RUBY_OPENCV_CVCONDENSATION_H - -#include "opencv.h" - -#define __NAMESPACE_BEGIN_CVCONDENSATION namespace cCvConDensation{ -#define __NAMESPACE_END_CVCONDENSATION } - -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVCONDENSATION - -VALUE rb_class(); -void define_ruby_class(); - -VALUE rb_dp(VALUE self); -VALUE rb_mp(VALUE self); -VALUE rb_dynamic_matrix(VALUE self); -VALUE rb_state(VALUE self); -VALUE rb_confidence(VALUE self); -VALUE rb_cumulative(VALUE self); -VALUE rb_samples_num(VALUE self); - -VALUE rb_init_sample_set(VALUE self, VALUE lower, VALUE upper); -VALUE rb_update_by_time(VALUE self); -VALUE rb_each_sample(VALUE self); -VALUE rb_calculate_confidence(VALUE self); - -__NAMESPACE_END_CVCONDENSATION - -inline CvConDensation* -CVCONDENSATION(VALUE object) -{ - CvConDensation *ptr; - Data_Get_Struct(object, CvConDensation, ptr); - return ptr; -} - -__NAMESPACE_END_OPENCV - -#endif // RUBY_OPENCV_CVCONDENSATION_H diff --git a/ext/cvconnectedcomp.cpp b/ext/cvconnectedcomp.cpp deleted file mode 100644 index a3f5907b..00000000 --- a/ext/cvconnectedcomp.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/************************************************************ - - cvconnectedcomp.cpp - - - $Author: lsxi $ - - Copyright (C) 2005-2007 Masakazu Yonekura - -************************************************************/ -#include "cvconnectedcomp.h" -/* - * Document-class: OpenCV::CvConnectedComp - * - * see CvMat#flood_fill - * - * C structure is here. - * typedef struct CvConnectedComp - * { - * double area; - * CvScalar value; - * CvRect rect; - * CvSeq* contour; - * } CvConnectedComp; - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVCONNECTEDCOMP - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - rb_klass = rb_define_class_under(opencv, "CvConnectedComp", rb_cObject); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_method(rb_klass, "area", RUBY_METHOD_FUNC(rb_area), 0); - rb_define_method(rb_klass, "value", RUBY_METHOD_FUNC(rb_value), 0); - rb_define_method(rb_klass, "rect", RUBY_METHOD_FUNC(rb_rect), 0); - rb_define_method(rb_klass, "rect=", RUBY_METHOD_FUNC(rb_set_rect), 0); -} - -VALUE -rb_allocate(VALUE klass) -{ - CvConnectedComp *ptr; - return Data_Make_Struct(klass, CvConnectedComp, 0, -1, ptr); -} - -/* - * Return area of connected component. - */ -VALUE -rb_area(VALUE self) -{ - return rb_float_new(CVCONNECTEDCOMP(self)->area); -} - -/* - * Return average color of the connected component. - */ -VALUE -rb_value(VALUE self) -{ - return REFER_OBJECT(cCvScalar::rb_class(), &CVCONNECTEDCOMP(self)->value, self); -} - -/* - * Return ROI of the component. - */ -VALUE -rb_rect(VALUE self) -{ - return REFER_OBJECT(cCvRect::rb_class(), &CVCONNECTEDCOMP(self)->rect, self); -} - -/* - * Set ROI of the component. - */ -VALUE -rb_set_rect(VALUE self, VALUE rect) -{ - CVCONNECTEDCOMP(self)->rect = VALUE_TO_CVRECT(rect); - return self; -} - -VALUE -new_object() -{ - return rb_allocate(rb_klass); -} - -VALUE -new_object(CvConnectedComp comp) -{ - VALUE object = rb_allocate(rb_klass); - *CVCONNECTEDCOMP(object) = comp; - return object; -} - -__NAMESPACE_END_CVCONNECTEDCOMP -__NAMESPACE_END_OPENCV diff --git a/ext/cvcontour.cpp b/ext/cvcontour.cpp deleted file mode 100644 index 2678b833..00000000 --- a/ext/cvcontour.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/************************************************************ - - cvcontour.cpp - - - $Author: lsxi $ - - Copyright (C) 2007 Masakazu Yonekura - -************************************************************/ -#include "cvcontour.h" -/* - * Document-class: OpenCV::CvContour - * - * Contour. - * CvMat#find_contours - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVCONTOUR - -#define APPROX_POLY_OPTION(op) NIL_P(op) ? rb_const_get(rb_class(), rb_intern("APPROX_OPTION")) : rb_funcall(rb_const_get(rb_class(), rb_intern("APPROX_OPTION")), rb_intern("merge"), 1, op) -#define APPROX_POLY_METHOD(op) CVMETHOD("APPROX_POLY_METHOD", rb_hash_aref(op, ID2SYM(rb_intern("method"))), CV_POLY_APPROX_DP) -#define APPROX_POLY_ACCURACY(op) NUM2DBL(rb_hash_aref(op, ID2SYM(rb_intern("accuracy")))) -#define APPROX_POLY_RECURSIVE(op) ({VALUE _recursive = rb_hash_aref(op, ID2SYM(rb_intern("recursive"))); NIL_P(_recursive) ? 0 : _recursive == Qfalse ? 0 : 1;}) - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * cvseq = rb_define_class_under(opencv, "CvSeq"); - * curve = rb_define_module_under(opencv, "Curve"); - * pointset = rb_define_module_under(opencv, "PointSet"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - VALUE cvseq = cCvSeq::rb_class(); - VALUE curve = mCurve::rb_module(); - VALUE pointset = mPointSet::rb_module(); - - rb_klass = rb_define_class_under(opencv, "CvContour", cvseq); - rb_include_module(rb_klass, curve); - rb_include_module(rb_klass, pointset); - - VALUE approx_option = rb_hash_new(); - rb_define_const(rb_klass, "APPROX_OPTION", approx_option); - rb_hash_aset(approx_option, ID2SYM(rb_intern("method")), INT2FIX(CV_POLY_APPROX_DP)); - rb_hash_aset(approx_option, ID2SYM(rb_intern("accuracy")), rb_float_new(1.0)); - rb_hash_aset(approx_option, ID2SYM(rb_intern("recursive")), Qfalse); - - rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); - rb_define_method(rb_klass, "rect", RUBY_METHOD_FUNC(rb_rect), 0); - rb_define_method(rb_klass, "color", RUBY_METHOD_FUNC(rb_color), 0); - rb_define_method(rb_klass, "color=", RUBY_METHOD_FUNC(rb_set_color), 1); - rb_define_method(rb_klass, "reserved", RUBY_METHOD_FUNC(rb_reserved), 0); - rb_define_method(rb_klass, "approx_poly", RUBY_METHOD_FUNC(rb_approx_poly), -1); - rb_define_alias(rb_klass, "approx", "approx_poly"); - rb_define_method(rb_klass, "bounding_rect", RUBY_METHOD_FUNC(rb_bounding_rect), 0); - rb_define_method(rb_klass, "create_tree", RUBY_METHOD_FUNC(rb_create_tree), -1); - rb_define_method(rb_klass, "in?", RUBY_METHOD_FUNC(rb_in_q), 1); - rb_define_method(rb_klass, "measure_distance", RUBY_METHOD_FUNC(rb_measure_distance), 1); -} - -VALUE -rb_initialize(int argc, VALUE *argv, VALUE self) -{ - /* - VALUE storage; - CvSeq *seq = 0; - rb_scan_args(argc, argv, "01", &storage); - - storage = CHECK_CVMEMSTORAGE(storage); - seq = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint), CVMEMSTORAGE(storage)); - DATA_PTR(self) = seq; - resist_root_object(seq, storage); - st_insert(cCvSeq::seqblock_klass, (st_data_t)seq, (st_data_t)klass); - */ - return self; -} - -VALUE -rb_rect(VALUE self) -{ - return cCvRect::new_object(CVCONTOUR(self)->rect); -} - -VALUE -rb_color(VALUE self) -{ - return INT2NUM(CVCONTOUR(self)->color); -} - -VALUE -rb_set_color(VALUE self, VALUE color) -{ - CVCONTOUR(self)->color = NUM2INT(color); - return self; -} - -VALUE -rb_reserved(VALUE self) -{ - return rb_ary_new3(3, - INT2NUM(CVCONTOUR(self)->reserved[0]), - INT2NUM(CVCONTOUR(self)->reserved[1]), - INT2NUM(CVCONTOUR(self)->reserved[2])); -} - -/* - * call-seq: - * approx_poly(approx_poly_option) -> cvcontour - * - * Approximates polygonal curve(s) with desired precision. - * approx_poly_option should be Hash include these keys. - * :method - Approximation method. - * :dp - corresponds to Douglas-Peucker algorithm. - * :accuracy - approximation accuracy. (high-accuracy will create more simple contours) - * :recursive - (default false) - * If not nil or false, the function approximates all chains that access can be obtained to - * from self by h_next or v_next links. If 0, approximated this one. - */ - -VALUE -rb_approx_poly(int argc, VALUE *argv, VALUE self) -{ - VALUE approx_poly_option, storage; - rb_scan_args(argc, argv, "01", &approx_poly_option); - approx_poly_option = APPROX_POLY_OPTION(approx_poly_option); - storage = cCvMemStorage::new_object(); - /* - CvSeq *contour = cvApproxPoly(CVCONTOUR(self), sizeof(CvContour), CVMEMSTORAGE(storage), - APPROX_POLY_METHOD(approx_poly_option), - APPROX_POLY_ACCURACY(approx_poly_option), - APPROX_POLY_RECURSIVE(approx_poly_option)); - return cCvSeq::new_sequence(cCvContour::rb_class(), contour, cCvPoint::rb_class(), storage); - */ - return Qnil; -} - -/* - * call-seq: - * bounding_rect -> rect - * - * Calculates up-right bounding rectangle of point set. - * - */ -VALUE -rb_bounding_rect(VALUE self) -{ - return cCvRect::new_object(cvBoundingRect(CVCONTOUR(self), 1)); -} - -/* - * call-seq: - * create_tree([threshold = 0.0]) -> cvcontourtree - * - * Creates hierarchical representation of contour. - * If the parameter threshold is less than or equal to 0, - * the method creates full binary tree representation. - * If the threshold is greater than 0, the function creates - * representation with the precision threshold: - */ -VALUE -rb_create_tree(int argc, VALUE *argv, VALUE self) -{ - VALUE threshold, storage; - rb_scan_args(argc, argv, "01", &threshold); - storage = cCvMemStorage::new_object(); - CvContourTree *tree = cvCreateContourTree(CVSEQ(self), CVMEMSTORAGE(storage), IF_DBL(threshold, 0.0)); - return cCvSeq::new_sequence(cCvContourTree::rb_class(), (CvSeq*)tree, cCvPoint::rb_class(), storage); -} - -/* - * call-seq: - * in?(point) -> true or nil or false - * - * Determines whether the point is inside contour(true), outside(false), or lies on an edge(nil). - */ -VALUE -rb_in_q(VALUE self, VALUE point) -{ - double n = cvPointPolygonTest(CVARR(self), VALUE_TO_CVPOINT2D32F(point), 0); - return n == 0 ? Qnil : n > 0 ? Qtrue : Qfalse; -} - -/* - * call-seq: - * measure_distance(point) -> float - * - * Return distance between the point and the nearest contour edge. - */ -VALUE -rb_measure_distance(VALUE self, VALUE point) -{ - return rb_float_new(cvPointPolygonTest(CVARR(self), VALUE_TO_CVPOINT2D32F(point), 1)); -} - - -VALUE new_object() -{ - VALUE storage = cCvMemStorage::new_object(); - CvSeq *seq = cvCreateSeq(CV_SEQ_CONTOUR, sizeof(CvContour), sizeof(CvPoint), CVMEMSTORAGE(storage)); - VALUE object = cCvSeq::new_sequence(cCvContour::rb_class(), seq, cCvPoint::rb_class(), storage); - return object; -} - -__NAMESPACE_END_CVCONTOUR -__NAMESPACE_END_OPENCV - diff --git a/ext/cverror.cpp b/ext/cverror.cpp deleted file mode 100644 index 7220a729..00000000 --- a/ext/cverror.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/************************************************************ - - cverror.cpp - - - $Author: lsxi $ - - Copyright (C) 2005-2006 Masakazu Yonekura - -************************************************************/ -#include "cverror.h" -/* - * Document-module: OpenCV::CvError - * - * =Internal OpenCV errors - * - * This module collect OpenCV internal error wrapper classes. - * * CvStatusBackTrace - * * CvStatusError - * * CvStatusInternal - * * CvStatusNoMemory - * * CvStatusBadArgument - * * CvStatusNoConverge - * * CvStatusAutoTrace - * - * * CvHeaderIsNull - * * CvBadImageSize - * * CvBadOffset - * * CvBadDataPointer - * * CvBadStep - * * CvBadModelOrChannelSequence - * * CvBadNumChannels - * * CvBadAlphaChannel - * * CvBadOrder - * * CvBadOrigin - * * CvBadAlign - * * CvBadCallback - * * CvBadTileSize - * * CvBadCOI - * * CvBadROISize - * - * * CvMaskIsTiled - * - * * CvStatusNullPointer - * * CvStatusVectorLengthError - * * CvStatusFilterStructContentError - * * CvStatusKernelStructContentError - * * CvStatusFilterOffsetError - * - * * CvStatusBadSize - * * CvStatusDivByZero - * * CvStatusInplaceNotSupported - * * CvStatusObjectNotFound - * * CvStatusUnmatchedFormant - * * CvStatusUnsupportedFormats - * * CvStatusOutOfRange - * * CvStatusParseError - * * CvStatusNotImplemented - * * CvStsBadMemoryBlock - */ -#define RESIST_CVERROR(object_name, error_code, parent) st_insert(cv_error, (st_data_t)error_code, (st_data_t)rb_define_class_under(rb_module_opencv(), object_name, parent)) - -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVERROR - -st_table *cv_error = st_init_numtable(); - -VALUE module; - -void -define_ruby_module() -{ - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - module = rb_define_module_under(opencv, "CvError"); - RESIST_CVERROR("CvStatusBackTrace", CV_StsBackTrace, rb_eStandardError); - RESIST_CVERROR("CvStatusError", CV_StsError, rb_eStandardError); - RESIST_CVERROR("CvStatusInternal", CV_StsInternal, rb_eStandardError); - RESIST_CVERROR("CvStatusNoMemory", CV_StsNoMem, rb_eNoMemError); - RESIST_CVERROR("CvStatusBadArgument", CV_StsBadArg, rb_eArgError); - RESIST_CVERROR("CvStatusBadFunction", CV_StsBadFunc, rb_eStandardError); - RESIST_CVERROR("CvStatusNoConverge", CV_StsNoConv, rb_eStandardError); - RESIST_CVERROR("CvStatusAutoTrace", CV_StsAutoTrace, rb_eStandardError); - - RESIST_CVERROR("CvHeaderIsNull", CV_HeaderIsNull, rb_eStandardError); - RESIST_CVERROR("CvBadImageSize", CV_BadImageSize, rb_eRangeError); - RESIST_CVERROR("CvBadOffset", CV_BadOffset, rb_eStandardError); - RESIST_CVERROR("CvBadDataPointer", CV_BadDataPtr, rb_eStandardError); - RESIST_CVERROR("CvBadStep", CV_BadStep, rb_eStandardError); - RESIST_CVERROR("CvBadModelOrChannelSequence", CV_BadModelOrChSeq, rb_eStandardError); - RESIST_CVERROR("CvBadNumChannels", CV_BadNumChannels, rb_eStandardError); - RESIST_CVERROR("CvBadNumChannel1U", CV_BadNumChannel1U, rb_eStandardError); - RESIST_CVERROR("CvNBadDepth", CV_BadDepth, rb_eStandardError); - RESIST_CVERROR("CvBadAlphaChannel", CV_BadAlphaChannel, rb_eStandardError); - RESIST_CVERROR("CvBadOrder", CV_BadOrder, rb_eStandardError); - RESIST_CVERROR("CvBadOrigin", CV_BadOrigin, rb_eStandardError); - RESIST_CVERROR("CvBadAlign", CV_BadAlign, rb_eStandardError); - RESIST_CVERROR("CvBadCallBack", CV_BadCallBack, rb_eStandardError); - RESIST_CVERROR("CvBadTileSize", CV_BadTileSize, rb_eStandardError); - RESIST_CVERROR("CvBadCOI", CV_BadCOI, rb_eStandardError); - RESIST_CVERROR("CvBadROISize", CV_BadROISize, rb_eStandardError); - - RESIST_CVERROR("CvMaskIsTiled", CV_MaskIsTiled, rb_eStandardError); - - RESIST_CVERROR("CvStatusNullPointer", CV_StsNullPtr, rb_eStandardError); - RESIST_CVERROR("CvStatusVectorLengthError", CV_StsVecLengthErr, rb_eStandardError); - RESIST_CVERROR("CvStatusFilterStructContentError", CV_StsFilterStructContentErr, rb_eStandardError); - RESIST_CVERROR("CvStatusKernelStructContentError", CV_StsKernelStructContentErr, rb_eStandardError); - RESIST_CVERROR("CvStatusFilterOffsetError", CV_StsFilterOffsetErr, rb_eStandardError); - - RESIST_CVERROR("CvStatusBadSize", CV_StsBadSize, rb_eStandardError); - RESIST_CVERROR("CvStatusDivByZero", CV_StsDivByZero, rb_eStandardError); - RESIST_CVERROR("CvStatusInplaceNotSupported", CV_StsInplaceNotSupported, rb_eStandardError); - RESIST_CVERROR("CvStatusObjectNotFound", CV_StsObjectNotFound, rb_eStandardError); - RESIST_CVERROR("CvStatusUnmatchedFormats", CV_StsUnmatchedFormats, rb_eStandardError); - RESIST_CVERROR("CvStatusBadFlag", CV_StsBadFlag, rb_eStandardError); - RESIST_CVERROR("CvStatusBadPoint", CV_StsBadPoint, rb_eStandardError); - RESIST_CVERROR("CvStatusBadMask", CV_StsBadMask, rb_eStandardError); - RESIST_CVERROR("CvStatusUnmatchedSizes", CV_StsUnmatchedSizes, rb_eStandardError); - RESIST_CVERROR("CvStatusUnsupportedFormat", CV_StsUnsupportedFormat, rb_eStandardError); - RESIST_CVERROR("CvStatusOutOfRange", CV_StsOutOfRange, rb_eStandardError); - RESIST_CVERROR("CvStatusParseError", CV_StsParseError, rb_eStandardError); - RESIST_CVERROR("CvStatusNotImplemented", CV_StsNotImplemented, rb_eNotImpError); - RESIST_CVERROR("CvStsBadMemoryBlock", CV_StsBadMemBlock,rb_eStandardError); -} - -VALUE -by_code(int error_code) -{ - VALUE klass = 0; - st_lookup(cv_error, (st_data_t)error_code, (st_data_t*)&klass); - return klass ? klass : rb_eStandardError; -} - -__NAMESPACE_END_CVERROR -__NAMESPACE_END_OPENCV diff --git a/ext/cverror.h b/ext/cverror.h deleted file mode 100644 index 455f3e67..00000000 --- a/ext/cverror.h +++ /dev/null @@ -1,79 +0,0 @@ -/************************************************************ - - cverror.h - - - $Author: lsxi $ - - Copyright (C) 2005-2006 Masakazu Yonekura - -************************************************************/ -#ifndef RUBY_OPENCV_CVERROR_H -#define RUBY_OPENCV_CVERROR_H - -#include "opencv.h" - -#define __NAMESPACE_BEGIN_CVERROR namespace mCvError{ -#define __NAMESPACE_END_CVERROR } - -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVERROR - -/* - VALUE - status_back_trace, - status_error, - status_internal, - status_no_memory, - status_bad_argument, - status_bad_function, - status_no_converge, - status_auto_trace, - - header_is_null, - bad_image_size, - bad_offset, - bad_data_pointer, - bad_step, - bad_model_or_channel_seqence, - bad_num_channels, - bad_num_channel1U, - bad_depth, - bad_alpha_channel, - bad_order, - bad_origin, - bad_align, - bad_callback, - bad_tile_size, - bad_COI, - bad_ROI_size, - - mask_is_tiled, - - status_null_pointer, - status_vector_length_error, - status_filter_struct_content_error, - status_kernel_struct_content_error, - status_filter_offset_error, - - status_bad_size, - status_div_by_zero, - status_inplace_not_supported, - status_object_not_found, - status_unmatched_formats, - status_bad_flags, - status_bad_point, - status_bad_mask, - status_unmatched_sizes, - status_unsupported_format, - status_out_of_range, - status_parse_error, - status_not_implemented, - status_bad_memory_block; -*/ -void define_ruby_module(); -VALUE by_code(int error_code); - -__NAMESPACE_END_CVERROR -__NAMESPACE_END_OPENCV - -#endif // RUBY_OPENCV_CVERROR_H diff --git a/ext/cvfont.cpp b/ext/cvfont.cpp deleted file mode 100644 index c390a9b5..00000000 --- a/ext/cvfont.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/************************************************************ - - cvfont.cpp - - - $Author: lsxi $ - - Copyright (C) 2005-2006 Masakazu Yonekura - -************************************************************/ -#include "cvfont.h" -/* - * Document-class: OpenCV::CvFont - * - * Font structure that can be passed to text rendering functions. - * see CvMat#put_text, CvMat#put_text! - */ - -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVFONT - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - rb_klass = rb_define_class_under(opencv, "CvFont", rb_cObject); - rb_define_alloc_func(rb_klass, rb_allocate); - VALUE face = rb_hash_new(); - rb_define_const(rb_klass, "FACE", face); - rb_hash_aset(face, ID2SYM(rb_intern("simplex")), INT2FIX(CV_FONT_HERSHEY_SIMPLEX)); - rb_hash_aset(face, ID2SYM(rb_intern("plain")), INT2FIX(CV_FONT_HERSHEY_PLAIN)); - rb_hash_aset(face, ID2SYM(rb_intern("duplex")), INT2FIX(CV_FONT_HERSHEY_DUPLEX)); - rb_hash_aset(face, ID2SYM(rb_intern("triplex")), INT2FIX(CV_FONT_HERSHEY_TRIPLEX)); - rb_hash_aset(face, ID2SYM(rb_intern("complex_small")), INT2FIX(CV_FONT_HERSHEY_COMPLEX_SMALL)); - rb_hash_aset(face, ID2SYM(rb_intern("script_simplex")), INT2FIX(CV_FONT_HERSHEY_SCRIPT_SIMPLEX)); - rb_hash_aset(face, ID2SYM(rb_intern("script_complex")), INT2FIX(CV_FONT_HERSHEY_SCRIPT_COMPLEX)); - - VALUE default_option = rb_hash_new(); - rb_define_const(rb_klass, "FONT_OPTION", default_option); - rb_hash_aset(default_option, ID2SYM(rb_intern("hscale")), rb_float_new(1.0)); - rb_hash_aset(default_option, ID2SYM(rb_intern("vscale")), rb_float_new(1.0)); - rb_hash_aset(default_option, ID2SYM(rb_intern("shear")), INT2FIX(0)); - rb_hash_aset(default_option, ID2SYM(rb_intern("thickness")), INT2FIX(1)); - rb_hash_aset(default_option, ID2SYM(rb_intern("line_type")), INT2FIX(8)); - - rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); -} - -VALUE -rb_allocate(VALUE klass) -{ - CvFont *ptr; - return Data_Make_Struct(klass, CvFont, 0, -1, ptr); -} - - -/* - * call-seq: - * CvFont.new(face[,font_option]) -> font - * - * Create font object. - * face is font name identifier. - * - * Only a subset of Hershey fonts (http://sources.isc.org/utils/misc/hershey-font.txt) are supported now: - * * :simplex - normal size sans-serif font - * * :plain - small size sans-serif font - * * :duplex - normal size sans-serif font (more complex than :simplex) - * * :complex - normal size serif font - * * :triplex - normal size serif font (more complex than :complex) - * * :complex_small - smaller version of :complex - * * :script_simplex - hand-writing style font - * * :script_complex - more complex variant of :script_simplex - * - * font_option should be Hash include these keys. - * :hscale - * Horizontal scale. If equal to 1.0, the characters have the original width depending on the font type. - * If equal to 0.5, the characters are of half the original width. - * :vscale - * Vertical scale. If equal to 1.0, the characters have the original height depending on the font type. - * If equal to 0.5, the characters are of half the original height. - * :shear - * Approximate tangent of the character slope relative to the vertical line. - * Zero value means a non-italic font, 1.0f means ~45degree slope, etc. - * :thickness - * Thickness of the text strokes. - * :line_type - * Type of the strokes, see CvMat#Line description. - * :italic - * If value is not nil or false that means italic or oblique font. - * - * note: font_option's default value is CvFont::FONT_OPTION. - * - * e.g. Create Font - * OpenCV::CvFont.new(:simplex, :hscale => 2, :vslace => 2, :italic => true) - * # create 2x bigger than normal, italic type font. - */ -VALUE -rb_initialize(int argc, VALUE *argv, VALUE self) -{ - VALUE face, font_option; - rb_scan_args(argc, argv, "11", &face, &font_option); - Check_Type(face, T_SYMBOL); - face = rb_hash_aref(rb_const_get(cCvFont::rb_class(), rb_intern("FACE")), face); - if (NIL_P(face)) { - rb_raise(rb_eArgError, "undefined face."); - } - font_option = FONT_OPTION(font_option); - /* - cvInitFont(CVFONT(self), - (FIX2INT(face) | FO_ITALIC(font_option)), - FO_HSCALE(font_option), - FO_VSCALE(font_option), - FO_SHEAR(font_option), - FO_THICKNESS(font_option), - FO_LINE_TYPE(font_option)); - */ - return self; -} - - -VALUE -rb_face(VALUE self) -{ - return FIX2INT(CVFONT(self)->font_face); -} - -VALUE -rb_hscale(VALUE self) -{ - return rb_float_new(CVFONT(self)->hscale); -} - -VALUE -rb_vscale(VALUE self) -{ - return rb_float_new(CVFONT(self)->vscale); -} - -VALUE -rb_shear(VALUE self) -{ - return rb_float_new(CVFONT(self)->shear); -} - -VALUE -rb_thickness(VALUE self) -{ - return FIX2INT(CVFONT(self)->thickness); -} - -VALUE -rb_line_type(VALUE self) -{ - return FIX2INT(CVFONT(self)->line_type); -} - -__NAMESPACE_END_CVFONT -__NAMESPACE_END_OPENCV diff --git a/ext/cvfont.h b/ext/cvfont.h deleted file mode 100644 index 1b76090e..00000000 --- a/ext/cvfont.h +++ /dev/null @@ -1,56 +0,0 @@ -/************************************************************ - - cvfont.h - - - $Author: lsxi $ - - Copyright (C) 2005-2006 Masakazu Yonekura - -************************************************************/ -#ifndef RUBY_OPENCV_CVFONT_H -#define RUBY_OPENCV_CVFONT_H - -#include "opencv.h" - -#define __NAMESPACE_BEGIN_CVFONT namespace cCvFont{ -#define __NAMESPACE_END_CVFONT } - -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVFONT - -#define FONT_OPTION(op) NIL_P(op) ? rb_const_get(rb_class(), rb_intern("FONT_OPTION")) : rb_funcall(rb_const_get(rb_class(), rb_intern("FONT_OPTION")), rb_intern("merge"), 1, font_option) -#define FO_ITALIC(op) ({VALUE _italic = rb_hash_aref(op, ID2SYM(rb_intern("italic"))); NIL_P(_italic) ? 0 : _italic == Qfalse ? 0 : 1;}) -#define FO_HSCALE(op) NUM2DBL(rb_hash_aref(op, ID2SYM(rb_intern("hscale")))) -#define FO_VSCALE(op) NUM2DBL(rb_hash_aref(op, ID2SYM(rb_intern("vscale")))) -#define FO_SHEAR(op) NUM2DBL(rb_hash_aref(op, ID2SYM(rb_intern("shear")))) -#define FO_THICKNESS(op) FIX2INT(rb_hash_aref(op, ID2SYM(rb_intern("thickness")))) -#define FO_LINE_TYPE(op) FIX2INT(rb_hash_aref(op, ID2SYM(rb_intern("line_type"))) == ID2SYM("aa") ? INT2FIX(CV_AA) : rb_hash_aref(op, ID2SYM(rb_intern("line_type")))) - - -VALUE rb_class(); - -void define_ruby_class(); - -VALUE rb_allocate(VALUE klass); -VALUE rb_initialize(int argc, VALUE *argv, VALUE self); - -VALUE rb_face(VALUE self); -VALUE rb_hscale(VALUE self); -VALUE rb_vscale(VALUE self); -VALUE rb_shear(VALUE self); -VALUE rb_thickness(VALUE self); -VALUE rb_line_type(VALUE self); - -__NAMESPACE_END_CVFONT - -inline CvFont* -CVFONT(VALUE object) -{ - CvFont *ptr; - Data_Get_Struct(object, CvFont, ptr); - return ptr; -} - -__NAMESPACE_END_OPENCV - -#endif // RUBY_OPENCV_CVFONT_H diff --git a/ext/cvhaarclassifiercascade.cpp b/ext/cvhaarclassifiercascade.cpp deleted file mode 100644 index 27cf28a6..00000000 --- a/ext/cvhaarclassifiercascade.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/************************************************************ - - cvhaarclassifercascade.cpp - - - $Author: lsxi $ - - Copyright (C) 2005-2007 Masakazu Yonekura - -************************************************************/ -#include "cvhaarclassifiercascade.h" -/* - * Document-class: OpenCV::CvHaarClassifierCascade - * - * CvHaarClassifierCascade object is "fast-object-detector". - * This detector can discover object (e.g. human's face) from image. - * - * Find face-area from picture "lena"... - * link:../images/face_detect_from_lena.jpg - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVHAARCLASSIFERCASCADE - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - rb_klass = rb_define_class_under(opencv, "CvHaarClassifierCascade", rb_cObject); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_singleton_method(rb_klass, "load", RUBY_METHOD_FUNC(rb_load), 1); - rb_define_method(rb_klass, "detect_objects", RUBY_METHOD_FUNC(rb_detect_objects), -1); - rb_define_method(rb_klass, "detect_objects_with_pruning", RUBY_METHOD_FUNC(rb_detect_objects_with_pruning), -1); -} - -VALUE -rb_allocate(VALUE klass) -{ - return OPENCV_OBJECT(klass, 0); -} - -/* - * call-seq: - * CvHaarClassiferCascade.load(path) -> object-detector - * - * Load trained cascade of haar classifers from file. - * Object detection classifiers are stored in XML or YAML files. - * sample of object detection classifier files is included by OpenCV. - * - * You can found these at - * C:\Program Files\OpenCV\data\haarcascades\*.xml (Windows, default install path) - * - * e.g. you want to try to detect human's face. - * detector = CvHaarClassiferCascade.load("haarcascade_frontalface_alt.xml") - */ -VALUE -rb_load(VALUE klass, VALUE path) -{ - CvHaarClassifierCascade *cascade = (CvHaarClassifierCascade*)cvLoad(StringValueCStr(path), 0, 0, 0); - if(!CV_IS_HAAR_CLASSIFIER(cascade)) - rb_raise(rb_eTypeError, "invalid format haar classifier cascade file."); - return OPENCV_OBJECT(rb_klass, cascade); -} - -VALUE -rb_save(VALUE self, VALUE path) -{ - rb_raise(rb_eNotImpError, ""); -} - -/* - * call-seq: - * detect_objects(image[,scale_factor = 1.1, min_neighbor = 3, min_size = CvSize.new(0,0)]) -> cvseq(include CvAvgComp object) - * detect_objects(image[,scale_factor = 1.1, min_neighbor = 3, min_size = CvSize.new(0,0)]){|cmp| ... } -> cvseq(include CvAvgComp object) - * - * Detects objects in the image. This method finds rectangular regions in the - * given image that are likely to contain objects the cascade has been trained - * for and return those regions as a sequence of rectangles. - * - * * scale_factor (should be > 1.0) - * The factor by which the search window is scaled between the subsequent scans, for example, 1.1 mean increasing window by 10%. - * * min_neighbors - * Minimum number (minus 1) of neighbor rectangles that makes up an object. - * All the groups of a smaller number of rectangles than min_neighbors - 1 are rejected. - * If min_neighbors is 0, the function does not any grouping at all and returns all the detected - * candidate rectangles, whitch many be useful if the user wants to apply a customized grouping procedure. - * * min_size - * Minimum window size. By default, it is set to size of samples the classifier has been trained on. - */ -VALUE -rb_detect_objects(int argc, VALUE *argv, VALUE self) -{ - VALUE image, storage, scale_factor, min_neighbors, min_size, result; - rb_scan_args(argc, argv, "14", &image, &storage, &scale_factor, &min_neighbors, &min_size); - if (!rb_obj_is_kind_of(image, cCvMat::rb_class())) - rb_raise(rb_eTypeError, "argument 1(target-image) should be %s.", rb_class2name(cCvMat::rb_class())); - double scale = IF_DBL(scale_factor, 1.1); - if (!(scale > 1.0)) - rb_raise(rb_eArgError, "argument 2 (scale factor) must > 1.0."); - storage = CHECK_CVMEMSTORAGE(storage); - CvSeq *seq = cvHaarDetectObjects(CVMAT(image), CVHAARCLASSIFIERCASCADE(self), CVMEMSTORAGE(storage), - scale, IF_INT(min_neighbors, 3), 0, NIL_P(min_size) ? cvSize(0,0) : VALUE_TO_CVSIZE(min_size)); - result = cCvSeq::new_sequence(cCvSeq::rb_class(), seq, cCvAvgComp::rb_class(), storage); - if (rb_block_given_p()) { - for(int i = 0; i < seq->total; i++) - rb_yield(REFER_OBJECT(cCvAvgComp::rb_class(), cvGetSeqElem(seq, i), storage)); - } - return result; -} - -/* - * call-seq: - * detect_objects_with_pruning(image[,scale_factor = 1.1, min_neighbor = 3, min_size = CvSize.new(0,0)]) -> cvseq(include CvAvgComp object) - * detect_objects_with_pruning(image[,scale_factor = 1.1, min_neighbor = 3, min_size = CvSize.new(0,0)]){|cmp| ... } -> cvseq(include CvAvgComp object) - * - * Almost same to #detect_objects (Return detected objects). - * - * Before scanning to image, Canny edge detector to reject some image regions - * that contain too few or too much edges, and thus can not contain the searched object. - * - * note: The particular threshold values are tuned for face detection. - * And in this case the pruning speeds up the processing. - */ -VALUE -rb_detect_objects_with_pruning(int argc, VALUE *argv, VALUE self) -{ - VALUE image, storage, scale_factor, min_neighbors, min_size, result; - rb_scan_args(argc, argv, "14", &image, &storage, &scale_factor, &min_neighbors, &min_size); - if (!rb_obj_is_kind_of(image, cCvMat::rb_class())) - rb_raise(rb_eTypeError, "argument 1(target-image) should be %s.", rb_class2name(cCvMat::rb_class())); - double scale = IF_DBL(scale_factor, 1.1); - if (!(scale > 1.0)) - rb_raise(rb_eArgError, "argument 2 (scale factor) must > 1.0."); - storage = CHECK_CVMEMSTORAGE(storage); - CvSeq *seq = cvHaarDetectObjects(CVMAT(image), CVHAARCLASSIFIERCASCADE(self), CVMEMSTORAGE(storage), - scale, IF_INT(min_neighbors, 3), CV_HAAR_DO_CANNY_PRUNING, NIL_P(min_size) ? cvSize(0,0) : VALUE_TO_CVSIZE(min_size)); - result = cCvSeq::new_sequence(cCvSeq::rb_class(), seq, cCvAvgComp::rb_class(), storage); - if (rb_block_given_p()) { - for(int i = 0; i < seq->total; i++) - rb_yield(REFER_OBJECT(cCvAvgComp::rb_class(), cvGetSeqElem(seq, i), storage)); - } - return result; -} - -__NAMESPACE_END_CVHAARCLASSIFERCASCADE -__NAMESPACE_END_OPENCV diff --git a/ext/cvhistogram.cpp b/ext/cvhistogram.cpp deleted file mode 100644 index 8738afad..00000000 --- a/ext/cvhistogram.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/************************************************************ - - cvhistogram.cpp - - - $Author: lsxi $ - - Copyright (C) 2005-2008 Masakazu Yonekura - -************************************************************/ -#include "cvhistogram.h" -/* - * Document-class: OpenCV::CvHistogram - * - * Muti-dimensional histogram. - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVHISTOGRAM - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - rb_klass = rb_define_class_under(opencv, "CvHistogram", rb_cObject); - - rb_define_method(rb_klass, "is_uniform?", RUBY_METHOD_FUNC(rb_is_uniform), 0); - rb_define_method(rb_klass, "is_sparse?", RUBY_METHOD_FUNC(rb_is_sparse), 0); - rb_define_method(rb_klass, "has_range?", RUBY_METHOD_FUNC(rb_has_range), 0); - rb_define_method(rb_klass, "dims", RUBY_METHOD_FUNC(rb_dims), 0); - - rb_define_method(rb_klass, "normalize", RUBY_METHOD_FUNC(rb_normalize), 1); - rb_define_method(rb_klass, "normalize!", RUBY_METHOD_FUNC(rb_normalize_bang), 1); - rb_define_method(rb_klass, "thresh", RUBY_METHOD_FUNC(rb_thresh), 1); - rb_define_alias(rb_klass, "threshold", "thresh"); - rb_define_method(rb_klass, "thresh!", RUBY_METHOD_FUNC(rb_thresh_bang), 1); - rb_define_alias(rb_klass, "threshold!", "thresh!"); -} - -VALUE -rb_allocate(VALUE klass) -{ - // not yet - return Qnil; -} - -/* - * call-seq: - * is_uniform? -> true or false - * - */ -VALUE -rb_is_uniform(VALUE self) -{ - return CV_IS_UNIFORM_HIST(CVHISTOGRAM(self)) ? Qtrue : Qfalse; -} - -/* - * call-seq: - * is_sparse? -> true or false - * - */ -VALUE -rb_is_sparse(VALUE self) -{ - return CV_IS_SPARSE_HIST(CVHISTOGRAM(self)) ? Qtrue : Qfalse; -} - -/* - * call-seq: - * has_range? -> true or false - */ -VALUE -rb_has_range(VALUE self) -{ - return CV_HIST_HAS_RANGES(CVHISTOGRAM(self)) ? Qtrue : Qfalse; -} - -/* - * call-seq: - * dims -> [int[,int...]] - */ -VALUE -rb_dims(VALUE self) -{ - int size[CV_MAX_DIM]; - int dims = cvGetDims(CVHISTOGRAM(self)->bins, size); - VALUE result = rb_ary_new2(dims); - for(int i = 0; i < dims; i++){ - rb_ary_store(result, i, INT2FIX(size[i])); - } - return result; -} - -/* - * call-seq: - * bins -> cvmatnd or cvsparsemat - */ -VALUE -rb_bins(VALUE self) -{ - CvHistogram *hist = CVHISTOGRAM(self); - return REFER_OBJECT(CV_IS_SPARSE_HIST(hist) ? cCvSparseMat::rb_class() : cCvMatND::rb_class(), hist->bins, self); -} - -/* - * call-seq: - * copy -> cvhist - * - * Clone histogram. - */ -VALUE -rb_copy(VALUE self) -{ - VALUE dest = 0; - CvHistogram *hist = CVHISTOGRAM(dest); - cvCopyHist(CVHISTOGRAM(self), &hist); - return dest; -} - -/* - * call-seq: - * clear! - * - * Sets all histogram bins to 0 in case of dense histogram and removes all histogram bins in case of sparse array. - */ -VALUE -rb_clear_bang(VALUE self) -{ - cvClearHist(CVHISTOGRAM(self)); - return self; -} - -/* - * call-seq: - * normalize(factor) -> cvhist - * - * Return normalized the histogram bins by scaling them, such that the sum of the bins becomes equal to factor. - */ -VALUE -rb_normalize(VALUE self, VALUE factor) -{ - return rb_normalize_bang(rb_copy(self), factor); -} - -/* - * call-seq: - * normalize!(factor) -> self - * - * normalizes the histogram bins by scaling them, such that the sum of the bins becomes equal to factor. - */ -VALUE -rb_normalize_bang(VALUE self, VALUE factor) -{ - cvNormalizeHist(CVHISTOGRAM(self), NUM2DBL(factor)); - return self; -} - -/* - * call-seq: - * thresh(factor) -> cvhist - * - * Return cleared histogram bins that are below the specified threshold. - */ -VALUE -rb_thresh(VALUE self, VALUE factor) -{ - return rb_thresh_bang(rb_copy(self), factor); -} - -/* - * call-seq: - * thresh!(factor) -> self - * - * Cleares histogram bins that are below the specified threshold. - */ -VALUE -rb_thresh_bang(VALUE self, VALUE factor) -{ - cvThreshHist(CVHISTOGRAM(self), NUM2DBL(factor)); - return self; -} - - -__NAMESPACE_END_CVHISTOGRAM -__NAMESPACE_END_OPENCV diff --git a/ext/cvhistogram.h b/ext/cvhistogram.h deleted file mode 100644 index be486d45..00000000 --- a/ext/cvhistogram.h +++ /dev/null @@ -1,51 +0,0 @@ -/************************************************************ - - cvhistogram.h - - - $Author: lsxi $ - - Copyright (C) 2005-2008 Masakazu Yonekura - -************************************************************/ -#ifndef RUBY_OPENCV_CVHISTOGRAM_H -#define RUBY_OPENCV_CVHISTOGRAM_H - -#include "opencv.h" - -#define __NAMESPACE_BEGIN_CVHISTOGRAM namespace cCvHistogram{ -#define __NAMESPACE_END_CVHISTOGRAM } - -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVHISTOGRAM - -VALUE rb_class(); - -void define_ruby_class(); - -VALUE rb_is_uniform(VALUE self); -VALUE rb_is_sparse(VALUE self); -VALUE rb_has_range(VALUE self); -VALUE rb_dims(VALUE self); -VALUE rb_bins(VALUE self); - -VALUE rb_clear(VALUE self); -VALUE rb_clear_bang(VALUE self); - -VALUE rb_normalize(VALUE self, VALUE factor); -VALUE rb_normalize_bang(VALUE self, VALUE factor); -VALUE rb_thresh(VALUE self, VALUE factor); -VALUE rb_thresh_bang(VALUE self, VALUE factor); - -__NAMESPACE_END_CVHISTOGRAM - -inline CvHistogram -*CVHISTOGRAM(VALUE object) -{ - CvHistogram *ptr; - Data_Get_Struct(object, CvHistogram, ptr); - return ptr; -} - -__NAMESPACE_END_OPENCV - -#endif // RUBY_OPENCV_CVHISTOGRAM_H diff --git a/ext/cvindex.cpp b/ext/cvindex.cpp deleted file mode 100644 index 99c91c02..00000000 --- a/ext/cvindex.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************ - - cvindex.cpp - - - $Author: lsxi $ - - Copyright (C) 2005 Masakazu Yonekura - -************************************************************/ -#include"cvindex.h" -/* - * Document-class: OpenCV::CvIndex - * - * - */ - -namespace mOpenCV{ - - namespace cCvIndex{ - VALUE rb_klass; - - VALUE rb_class(){ - return rb_klass; - } - - void define_ruby_class(){ - if(rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - rb_klass = rb_define_class_under(opencv, "CvIndex", rb_cObject); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); - rb_define_singleton_method(rb_klass, "cv_new", RUBY_METHOD_FUNC(rb_cv_new), -1); - rb_define_method(rb_klass, "value", RUBY_METHOD_FUNC(rb_value), 0); - rb_define_method(rb_klass, "to_s", RUBY_METHOD_FUNC(rb_to_s), 0); - } - - VALUE rb_allocate(VALUE klass){ - CvIndex *ptr; - return Data_Make_Struct(rb_klass, CvIndex, 0, free, ptr); - } - - VALUE rb_initialize(int argc, VALUE *argv, VALUE self){ - VALUE value; - if(rb_scan_args(argc, argv, "01", &value) > 0){ - Check_Type(value, T_FIXNUM); - CVINDEX(self)->value = FIX2INT(value); - } - return self; - } - - VALUE rb_cv_new(int argc, VALUE *argv, VALUE klass){ - VALUE object = rb_allocate(klass); - return rb_initialize(argc, argv, object); - } - - VALUE rb_value(VALUE self){ - return INT2FIX(CVINDEX(self)->value); - } - - VALUE rb_to_s(VALUE self){ - return rb_funcall(INT2FIX(CVINDEX(self)->value), rb_intern("to_s"), 0); - } - - } - - -} diff --git a/ext/cvindex.h b/ext/cvindex.h deleted file mode 100644 index b415c9a1..00000000 --- a/ext/cvindex.h +++ /dev/null @@ -1,40 +0,0 @@ -/************************************************************ - - cvindex.h - - - $Author: lsxi $ - - Copyright (C) 2005 Masakazu Yonekura - -************************************************************/ -#ifndef RUBY_OPENCV_CVINDEX_H -#define RUBY_OPENCV_CVINDEX_H - -#include"opencv.h" - -namespace mOpenCV{ - - typedef struct CvIndex{ - int value; - }CvIndex; - - namespace cCvIndex{ - VALUE rb_class(); - - void define_ruby_class(); - - VALUE rb_allocate(VALUE klass); - VALUE rb_initialize(int argc, VALUE *argv, VALUE self); - VALUE rb_cv_new(int argc, VALUE *argv, VALUE klass); - VALUE rb_value(VALUE self); - VALUE rb_to_s(VALUE self); - } - - inline CvIndex *CVINDEX(VALUE object){ - CvIndex *ptr; - Data_Get_Struct(object, CvIndex, ptr); - return ptr; - } -} - -#endif // RUBY_OPENCV_CVINDEX_H diff --git a/ext/cvline.cpp b/ext/cvline.cpp deleted file mode 100644 index bc592a89..00000000 --- a/ext/cvline.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/************************************************************ - - cvline.cpp - - - $Author: lsxi $ - - Copyright (C) 2005-2006 Masakazu Yonekura - -************************************************************/ -#include "cvline.h" -/* - * Document-class: OpenCV::CvLine - * - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVLINE - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - rb_klass = rb_define_class_under(opencv, "CvLine", rb_cObject); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_method(rb_klass, "rho", RUBY_METHOD_FUNC(rb_rho), 0); - rb_define_method(rb_klass, "rho=", RUBY_METHOD_FUNC(rb_set_rho), 1); - rb_define_method(rb_klass, "theta", RUBY_METHOD_FUNC(rb_theta), 0); - rb_define_method(rb_klass, "theta=", RUBY_METHOD_FUNC(rb_set_theta), 1); -} - -VALUE -rb_allocate(VALUE klass) -{ - CvLine *ptr; - return Data_Make_Struct(klass, CvLine, 0, -1, ptr); -} - -/* - * Return parameter on rho. - */ -VALUE -rb_rho(VALUE self) -{ - return rb_float_new(CVLINE(self)->rho); -} - -/* - * call-seq: - * rho = val - * - * Set rho parameter, return self. - */ -VALUE -rb_set_rho(VALUE self, VALUE rho) -{ - CVLINE(self)->rho = NUM2DBL(rho); - return self; -} - -/* - * Return parameter on theta. - */ -VALUE -rb_theta(VALUE self) -{ - return rb_float_new(CVLINE(self)->theta); -} - -/* - * call-seq: - * y = val - * - * Set theta parameter, return self. - */ -VALUE -rb_set_theta(VALUE self, VALUE theta) -{ - CVLINE(self)->theta = NUM2DBL(theta); - return self; -} - -VALUE -new_object(CvLine line) -{ - VALUE object = rb_allocate(rb_klass); - *CVLINE(object) = line; - return object; -} - -__NAMESPACE_END_CVLINE -__NAMESPACE_END_OPENCV diff --git a/ext/cvmat.cpp b/ext/cvmat.cpp deleted file mode 100644 index d2a1280c..00000000 --- a/ext/cvmat.cpp +++ /dev/null @@ -1,4809 +0,0 @@ -/************************************************************ - - cvmat.cpp - - - $Author: lsxi $ - - Copyright (C) 2005-2008 Masakazu Yonekura - -************************************************************/ -#include "cvmat.h" -/* - * Document-class: OpenCV::CvMat - * - * CvMat is basic 2D matrix class in OpenCV. - * - * C structure is here. - * typedef struct CvMat{ - * int type; - * int step; - * int *refcount; - * union - * { - * uchar *ptr; - * short *s; - * int *i; - * float *fl; - * double *db; - * } data; - * #ifdef __cplusplus - * union - * { - * int rows; - * int height; - * }; - * union - * { - * int cols; - * int width; - * }; - * #else - * int rows; // number of row - * int cols; // number of columns - * }CvMat; - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVMAT - -#define SUPPORT_8UC1_ONLY(value) if (cvGetElemType(CVARR(value)) != CV_8UC1) {rb_raise(rb_eNotImpError, "support single-channel 8bit unsigned image only.");} -#define SUPPORT_8U_ONLY(value) if (CV_MAT_DEPTH(cvGetElemType(CVARR(value))) != CV_8U) {rb_raise(rb_eNotImpError, "support 8bit unsigned image only.");} -#define SUPPORT_C1_ONLY(value) if (CV_MAT_CN(cvGetElemType(CVARR(value))) != 1) {rb_raise(rb_eNotImpError, "support single-channel image only.");} -#define SUPPORT_C1C3_ONLY(value) if (CV_MAT_CN(cvGetElemType(CVARR(value))) != 1 && CV_MAT_CN(cvGetElemType(CVARR(value))) != 3) {rb_raise(rb_eNotImpError, "support single-channel or 3-channnel image only.");} - -#define DRAWING_OPTION(op) NIL_P(op) ? rb_const_get(rb_class(), rb_intern("DRAWING_OPTION")) : rb_funcall(rb_const_get(rb_class(), rb_intern("DRAWING_OPTION")), rb_intern("merge"), 1, op) -#define DO_COLOR(op) VALUE_TO_CVSCALAR(rb_hash_aref(op, ID2SYM(rb_intern("color")))) -#define DO_THICKNESS(op) FIX2INT(rb_hash_aref(op, ID2SYM(rb_intern("thickness")))) -#define DO_LINE_TYPE(op) FIX2INT(rb_hash_aref(op, ID2SYM(rb_intern("line_type"))) == ID2SYM("aa") ? INT2FIX(CV_AA) : rb_hash_aref(op, ID2SYM(rb_intern("line_type")))) -#define DO_SHIFT(op) FIX2INT(rb_hash_aref(op, ID2SYM(rb_intern("shift")))) -#define DO_IS_CLOSED(op) ({VALUE _is_closed = rb_hash_aref(op, ID2SYM(rb_intern("is_closed"))); NIL_P(_is_closed) ? 0 : _is_closed == Qfalse ? 0 : 1;}) - -#define GOOD_FEATURES_TO_TRACK_OPTION(op) NIL_P(op) ? rb_const_get(rb_class(), rb_intern("GOOD_FEATURES_TO_TRACK_OPTION")) : rb_funcall(rb_const_get(rb_class(), rb_intern("GOOD_FEATURES_TO_TRACK_OPTION")), rb_intern("merge"), 1, op) -#define GF_MAX(op) FIX2INT(rb_hash_aref(op, ID2SYM(rb_intern("max")))) -#define GF_MASK(op) MASK(rb_hash_aref(op, ID2SYM(rb_intern("mask")))) -#define GF_BLOCK_SIZE(op) FIX2INT(rb_hash_aref(op, ID2SYM(rb_intern("block_size")))) -#define GF_USE_HARRIS(op) TRUE_OR_FALSE(rb_hash_aref(op, ID2SYM(rb_intern("use_harris"))), 0) -#define GF_K(op) NUM2DBL(rb_hash_aref(op, ID2SYM(rb_intern("k")))) - -#define FLOOD_FILL_OPTION(op) NIL_P(op) ? rb_const_get(rb_class(), rb_intern("FLOOD_FILL_OPTION")) : rb_funcall(rb_const_get(rb_class(), rb_intern("FLOOD_FILL_OPTION")), rb_intern("merge"), 1, op) -#define FF_CONNECTIVITY(op) NUM2INT(rb_hash_aref(op, ID2SYM(rb_intern("connectivity")))) -#define FF_FIXED_RANGE(op) TRUE_OR_FALSE(rb_hash_aref(op, ID2SYM(rb_intern("fixed_range"))), 0) -#define FF_MASK_ONLY(op) TRUE_OR_FALSE(rb_hash_aref(op, ID2SYM(rb_intern("mask_only"))), 0) - -#define FIND_CONTOURS_OPTION(op) NIL_P(op) ? rb_const_get(rb_class(), rb_intern("FIND_CONTOURS_OPTION")) : rb_funcall(rb_const_get(rb_class(), rb_intern("FIND_CONTOURS_OPTION")), rb_intern("merge"), 1, op) -#define FC_MODE(op) FIX2INT(rb_hash_aref(op, ID2SYM(rb_intern("mode")))) -#define FC_METHOD(op) FIX2INT(rb_hash_aref(op, ID2SYM(rb_intern("method")))) -#define FC_OFFSET(op)VALUE_TO_CVPOINT(rb_hash_aref(op, ID2SYM(rb_intern("offset")))) - -#define OPTICAL_FLOW_HS_OPTION(op) NIL_P(op) ? rb_const_get(rb_class(), rb_intern("OPTICAL_FLOW_HS_OPTION")) : rb_funcall(rb_const_get(rb_class(), rb_intern("OPTICAL_FLOW_HS_OPTION")), rb_intern("merge"), 1, op) -#define HS_LAMBDA(op) NUM2DBL(rb_hash_aref(op, ID2SYM(rb_intern("lambda")))) -#define HS_CRITERIA(op) VALUE_TO_CVTERMCRITERIA(rb_hash_aref(op, ID2SYM(rb_intern("criteria")))) - -#define OPTICAL_FLOW_BM_OPTION(op) NIL_P(op) ? rb_const_get(rb_class(), rb_intern("OPTICAL_FLOW_BM_OPTION")) : rb_funcall(rb_const_get(rb_class(), rb_intern("OPTICAL_FLOW_BM_OPTION")), rb_intern("merge"), 1, op) -#define BM_BLOCK_SIZE(op) VALUE_TO_CVSIZE(rb_hash_aref(op, ID2SYM(rb_intern("block_size")))) -#define BM_SHIFT_SIZE(op) VALUE_TO_CVSIZE(rb_hash_aref(op, ID2SYM(rb_intern("shift_size")))) -#define BM_MAX_RANGE(op) VALUE_TO_CVSIZE(rb_hash_aref(op, ID2SYM(rb_intern("max_range")))) - -#define FIND_FUNDAMENTAL_MAT_OPTION(op) NIL_P(op) ? rb_const_get(rb_class(), rb_intern("FIND_FUNDAMENTAL_MAT_OPTION")) : rb_funcall(rb_const_get(rb_class(), rb_intern("FIND_FUNDAMENTAL_MAT_OPTION")), rb_intern("merge"), 1, op) -#define FFM_WITH_STATUS(op) TRUE_OR_FALSE(rb_hash_aref(op, ID2SYM(rb_intern("with_status"))), 0) -#define FFM_MAXIMUM_DISTANCE(op) NUM2DBL(rb_hash_aref(op, ID2SYM(rb_intern("maximum_distance")))) -#define FFM_DESIRABLE_LEVEL(op) NUM2DBL(rb_hash_aref(op, ID2SYM(rb_intern("desirable_level")))) - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - rb_klass = rb_define_class_under(opencv, "CvMat", rb_cObject); - rb_define_alloc_func(rb_klass, rb_allocate); - - VALUE drawing_option = rb_hash_new(); - rb_define_const(rb_klass, "DRAWING_OPTION", drawing_option); - rb_hash_aset(drawing_option, ID2SYM(rb_intern("color")), cCvScalar::new_object(cvScalarAll(0))); - rb_hash_aset(drawing_option, ID2SYM(rb_intern("thickness")), INT2FIX(1)); - rb_hash_aset(drawing_option, ID2SYM(rb_intern("line_type")), INT2FIX(8)); - rb_hash_aset(drawing_option, ID2SYM(rb_intern("shift")), INT2FIX(0)); - - VALUE good_features_to_track_option = rb_hash_new(); - rb_define_const(rb_klass, "GOOD_FEATURES_TO_TRACK_OPTION", good_features_to_track_option); - rb_hash_aset(good_features_to_track_option, ID2SYM(rb_intern("max")), INT2FIX(0xFF)); - rb_hash_aset(good_features_to_track_option, ID2SYM(rb_intern("mask")), Qnil); - rb_hash_aset(good_features_to_track_option, ID2SYM(rb_intern("block_size")), INT2FIX(3)); - rb_hash_aset(good_features_to_track_option, ID2SYM(rb_intern("use_harris")), Qfalse); - rb_hash_aset(good_features_to_track_option, ID2SYM(rb_intern("k")), rb_float_new(0.04)); - - VALUE flood_fill_option = rb_hash_new(); - rb_define_const(rb_klass, "FLOOD_FILL_OPTION", flood_fill_option); - rb_hash_aset(flood_fill_option, ID2SYM(rb_intern("connectivity")), INT2FIX(4)); - rb_hash_aset(flood_fill_option, ID2SYM(rb_intern("fixed_range")), Qfalse); - rb_hash_aset(flood_fill_option, ID2SYM(rb_intern("mask_only")), Qfalse); - - VALUE find_contours_option = rb_hash_new(); - rb_define_const(rb_klass, "FIND_CONTOURS_OPTION", find_contours_option); - rb_hash_aset(find_contours_option, ID2SYM(rb_intern("mode")), INT2FIX(CV_RETR_LIST)); - rb_hash_aset(find_contours_option, ID2SYM(rb_intern("method")), INT2FIX(CV_CHAIN_APPROX_SIMPLE)); - rb_hash_aset(find_contours_option, ID2SYM(rb_intern("offset")), cCvPoint::new_object(cvPoint(0,0))); - - VALUE optical_flow_hs_option = rb_hash_new(); - rb_define_const(rb_klass, "OPTICAL_FLOW_HS_OPTION", optical_flow_hs_option); - rb_hash_aset(optical_flow_hs_option, ID2SYM(rb_intern("lambda")), rb_float_new(0.0005)); - rb_hash_aset(optical_flow_hs_option, ID2SYM(rb_intern("criteria")), cCvTermCriteria::new_object(cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 1, 0.001))); - - VALUE optical_flow_bm_option = rb_hash_new(); - rb_define_const(rb_klass, "OPTICAL_FLOW_BM_OPTION", optical_flow_bm_option); - rb_hash_aset(optical_flow_bm_option, ID2SYM(rb_intern("block_size")), cCvSize::new_object(cvSize(4, 4))); - rb_hash_aset(optical_flow_bm_option, ID2SYM(rb_intern("shift_size")), cCvSize::new_object(cvSize(1, 1))); - rb_hash_aset(optical_flow_bm_option, ID2SYM(rb_intern("max_range")), cCvSize::new_object(cvSize(4, 4))); - - VALUE find_fundamental_matrix_option = rb_hash_new(); - rb_define_const(rb_klass, "FIND_FUNDAMENTAL_MAT_OPTION", find_fundamental_matrix_option); - rb_hash_aset(find_fundamental_matrix_option, ID2SYM(rb_intern("with_status")), Qfalse); - rb_hash_aset(find_fundamental_matrix_option, ID2SYM(rb_intern("maximum_distance")), rb_float_new(1.0)); - rb_hash_aset(find_fundamental_matrix_option, ID2SYM(rb_intern("desirable_level")), rb_float_new(0.99)); - - rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); - // Ruby/OpenCV original functions - rb_define_method(rb_klass, "method_missing", RUBY_METHOD_FUNC(rb_method_missing), -1); - rb_define_method(rb_klass, "to_s", RUBY_METHOD_FUNC(rb_to_s), 0); - rb_define_method(rb_klass, "has_parent?", RUBY_METHOD_FUNC(rb_has_parent_q), 0); - rb_define_method(rb_klass, "parent", RUBY_METHOD_FUNC(rb_parent), 0); - rb_define_method(rb_klass, "inside?", RUBY_METHOD_FUNC(rb_inside_q), 1); - rb_define_method(rb_klass, "to_IplConvKernel", RUBY_METHOD_FUNC(rb_to_IplConvKernel), 1); - rb_define_method(rb_klass, "create_mask", RUBY_METHOD_FUNC(rb_create_mask), 0); - - rb_define_method(rb_klass, "width", RUBY_METHOD_FUNC(rb_width), 0); - rb_define_alias(rb_klass, "columns", "width"); - rb_define_alias(rb_klass, "cols", "width"); - rb_define_method(rb_klass, "height", RUBY_METHOD_FUNC(rb_height), 0); - rb_define_alias(rb_klass, "rows", "height"); - rb_define_method(rb_klass, "depth", RUBY_METHOD_FUNC(rb_depth), 0); - rb_define_method(rb_klass, "channel", RUBY_METHOD_FUNC(rb_channel), 0); - rb_define_method(rb_klass, "data", RUBY_METHOD_FUNC(rb_data), 0); - - rb_define_method(rb_klass, "clone", RUBY_METHOD_FUNC(rb_clone), 0); - rb_define_method(rb_klass, "copy", RUBY_METHOD_FUNC(rb_copy), -1); - rb_define_method(rb_klass, "to_8u", RUBY_METHOD_FUNC(rb_to_8u), 0); - rb_define_method(rb_klass, "to_8s", RUBY_METHOD_FUNC(rb_to_8s), 0); - rb_define_method(rb_klass, "to_16u", RUBY_METHOD_FUNC(rb_to_16u), 0); - rb_define_method(rb_klass, "to_16s", RUBY_METHOD_FUNC(rb_to_16s), 0); - rb_define_method(rb_klass, "to_32s", RUBY_METHOD_FUNC(rb_to_32s), 0); - rb_define_method(rb_klass, "to_32f", RUBY_METHOD_FUNC(rb_to_32f), 0); - rb_define_method(rb_klass, "to_64f", RUBY_METHOD_FUNC(rb_to_64f), 0); - rb_define_method(rb_klass, "vector?", RUBY_METHOD_FUNC(rb_vector_q), 0); - rb_define_method(rb_klass, "square?", RUBY_METHOD_FUNC(rb_square_q), 0); - - rb_define_method(rb_klass, "to_CvMat", RUBY_METHOD_FUNC(rb_to_CvMat), 0); - rb_define_method(rb_klass, "sub_rect", RUBY_METHOD_FUNC(rb_sub_rect), -2); - rb_define_alias(rb_klass, "subrect", "sub_rect"); - rb_define_method(rb_klass, "slice_width", RUBY_METHOD_FUNC(rb_slice_width), 1); - rb_define_method(rb_klass, "slice_height", RUBY_METHOD_FUNC(rb_slice_height), 1); - rb_define_method(rb_klass, "row", RUBY_METHOD_FUNC(rb_row), -2); - rb_define_method(rb_klass, "col", RUBY_METHOD_FUNC(rb_col), -2); - rb_define_alias(rb_klass, "column", "col"); - rb_define_method(rb_klass, "each_row", RUBY_METHOD_FUNC(rb_each_row), 0); - rb_define_method(rb_klass, "each_col", RUBY_METHOD_FUNC(rb_each_col), 0); - rb_define_alias(rb_klass, "each_column", "each_col"); - rb_define_method(rb_klass, "diag", RUBY_METHOD_FUNC(rb_diag), -1); - rb_define_alias(rb_klass, "diagonal", "diag"); - rb_define_method(rb_klass, "size", RUBY_METHOD_FUNC(rb_size), 0); - rb_define_method(rb_klass, "dims", RUBY_METHOD_FUNC(rb_dims), 0); - rb_define_method(rb_klass, "dim_size", RUBY_METHOD_FUNC(rb_dim_size), 1); - rb_define_method(rb_klass, "[]", RUBY_METHOD_FUNC(rb_aref), -2); - rb_define_alias(rb_klass, "at", "[]"); - rb_define_method(rb_klass, "[]=", RUBY_METHOD_FUNC(rb_aset), -2); - rb_define_method(rb_klass, "fill", RUBY_METHOD_FUNC(rb_fill), -1); - rb_define_alias(rb_klass, "set", "fill"); - rb_define_method(rb_klass, "fill!", RUBY_METHOD_FUNC(rb_fill_bang), -1); - rb_define_alias(rb_klass, "set!", "fill!"); - rb_define_method(rb_klass, "clear", RUBY_METHOD_FUNC(rb_clear), 0); - rb_define_alias(rb_klass, "set_zero", "clear"); - rb_define_method(rb_klass, "clear!", RUBY_METHOD_FUNC(rb_clear_bang), 0); - rb_define_alias(rb_klass, "set_zero!", "clear!"); - rb_define_method(rb_klass, "identity", RUBY_METHOD_FUNC(rb_set_identity), -1); - rb_define_method(rb_klass, "identity!", RUBY_METHOD_FUNC(rb_set_identity_bang), -1); - rb_define_method(rb_klass, "range", RUBY_METHOD_FUNC(rb_range), -1); - rb_define_method(rb_klass, "range!", RUBY_METHOD_FUNC(rb_range_bang), -1); - - rb_define_method(rb_klass, "reshape", RUBY_METHOD_FUNC(rb_reshape), 1); - rb_define_method(rb_klass, "repeat", RUBY_METHOD_FUNC(rb_repeat), 1); - rb_define_method(rb_klass, "flip", RUBY_METHOD_FUNC(rb_flip), -1); - rb_define_method(rb_klass, "flip!", RUBY_METHOD_FUNC(rb_flip_bang), -1); - rb_define_method(rb_klass, "split", RUBY_METHOD_FUNC(rb_split), 0); - rb_define_singleton_method(rb_klass, "merge", RUBY_METHOD_FUNC(rb_merge), -2); - rb_define_method(rb_klass, "rand_shuffle", RUBY_METHOD_FUNC(rb_rand_shuffle), -1); - rb_define_method(rb_klass, "rand_shuffle!", RUBY_METHOD_FUNC(rb_rand_shuffle_bang), -1); - rb_define_method(rb_klass, "lut", RUBY_METHOD_FUNC(rb_lut), 1); - rb_define_method(rb_klass, "convert_scale", RUBY_METHOD_FUNC(rb_convert_scale), 1); - rb_define_method(rb_klass, "convert_scale_abs", RUBY_METHOD_FUNC(rb_convert_scale_abs), 1); - rb_define_method(rb_klass, "add", RUBY_METHOD_FUNC(rb_add), -1); - rb_define_alias(rb_klass, "+", "add"); - rb_define_method(rb_klass, "sub", RUBY_METHOD_FUNC(rb_sub), -1); - rb_define_alias(rb_klass, "-", "sub"); - rb_define_method(rb_klass, "mul", RUBY_METHOD_FUNC(rb_mul), -1); - rb_define_alias(rb_klass, "*", "mul"); - rb_define_method(rb_klass, "div", RUBY_METHOD_FUNC(rb_div), -1); - rb_define_alias(rb_klass, "/", "div"); - rb_define_method(rb_klass, "and", RUBY_METHOD_FUNC(rb_and), -1); - rb_define_alias(rb_klass, "&", "and"); - rb_define_method(rb_klass, "or", RUBY_METHOD_FUNC(rb_or), -1); - rb_define_alias(rb_klass, "|", "or"); - rb_define_method(rb_klass, "xor", RUBY_METHOD_FUNC(rb_xor), -1); - rb_define_alias(rb_klass, "^", "xor"); - rb_define_method(rb_klass, "not", RUBY_METHOD_FUNC(rb_not), 0); - rb_define_method(rb_klass, "not!", RUBY_METHOD_FUNC(rb_not_bang), 0); - rb_define_method(rb_klass, "eq", RUBY_METHOD_FUNC(rb_eq), 1); - rb_define_alias(rb_klass, "==", "eq"); - rb_define_method(rb_klass, "gt", RUBY_METHOD_FUNC(rb_gt), 1); - rb_define_alias(rb_klass, ">", "gt"); - rb_define_method(rb_klass, "ge", RUBY_METHOD_FUNC(rb_ge), 1); - rb_define_alias(rb_klass, ">=", "ge"); - rb_define_method(rb_klass, "lt", RUBY_METHOD_FUNC(rb_lt), 1); - rb_define_alias(rb_klass, "<", "lt"); - rb_define_method(rb_klass, "le", RUBY_METHOD_FUNC(rb_le), 1); - rb_define_alias(rb_klass, "<=", "le"); - rb_define_method(rb_klass, "ne", RUBY_METHOD_FUNC(rb_ne), 1); - rb_define_alias(rb_klass, "!=", "ne"); - rb_define_method(rb_klass, "in_range", RUBY_METHOD_FUNC(rb_in_range), 2); - rb_define_method(rb_klass, "abs_diff", RUBY_METHOD_FUNC(rb_abs_diff), 1); - rb_define_method(rb_klass, "count_non_zero", RUBY_METHOD_FUNC(rb_count_non_zero), 0); - rb_define_method(rb_klass, "sum", RUBY_METHOD_FUNC(rb_sum), 0); - rb_define_method(rb_klass, "avg", RUBY_METHOD_FUNC(rb_avg), -1); - rb_define_method(rb_klass, "avg_sdv", RUBY_METHOD_FUNC(rb_avg_sdv), -1); - rb_define_method(rb_klass, "sdv", RUBY_METHOD_FUNC(rb_sdv), -1); - rb_define_method(rb_klass, "min_max_loc", RUBY_METHOD_FUNC(rb_min_max_loc), -1); - rb_define_method(rb_klass, "dot_product", RUBY_METHOD_FUNC(rb_dot_product), 1); - rb_define_method(rb_klass, "cross_product", RUBY_METHOD_FUNC(rb_cross_product), 1); - rb_define_method(rb_klass, "transform", RUBY_METHOD_FUNC(rb_transform), -1); - rb_define_method(rb_klass, "perspective_transform", RUBY_METHOD_FUNC(rb_perspective_transform), 1); - rb_define_method(rb_klass, "mul_transposed", RUBY_METHOD_FUNC(rb_mul_transposed), -2); - rb_define_method(rb_klass, "trace", RUBY_METHOD_FUNC(rb_trace), 0); - rb_define_method(rb_klass, "transpose", RUBY_METHOD_FUNC(rb_transpose), 0); - rb_define_alias(rb_klass, "t", "transpose"); - rb_define_method(rb_klass, "transpose!", RUBY_METHOD_FUNC(rb_transpose_bang), 0); - rb_define_alias(rb_klass, "t!", "transpose!"); - rb_define_method(rb_klass, "det", RUBY_METHOD_FUNC(rb_det), 0); - rb_define_alias(rb_klass, "determinant", "det"); - rb_define_method(rb_klass, "invert", RUBY_METHOD_FUNC(rb_invert), -1); - rb_define_method(rb_klass, "solve", RUBY_METHOD_FUNC(rb_solve), -1); - rb_define_method(rb_klass, "svd", RUBY_METHOD_FUNC(rb_svd), -1); - rb_define_method(rb_klass, "svbksb", RUBY_METHOD_FUNC(rb_svbksb), -1); - rb_define_method(rb_klass, "eigenvv", RUBY_METHOD_FUNC(rb_eigenvv), -1); - rb_define_method(rb_klass, "eigenvv!", RUBY_METHOD_FUNC(rb_eigenvv_bang), -1); - rb_define_method(rb_klass, "calc_covar_matrix", RUBY_METHOD_FUNC(rb_calc_covar_matrix), -1); - rb_define_method(rb_klass, "mahalonobis", RUBY_METHOD_FUNC(rb_mahalonobis), -1); - - /* drawing function */ - rb_define_method(rb_klass, "line", RUBY_METHOD_FUNC(rb_line), -1); - rb_define_method(rb_klass, "line!", RUBY_METHOD_FUNC(rb_line_bang), -1); - rb_define_method(rb_klass, "rectangle", RUBY_METHOD_FUNC(rb_rectangle), -1); - rb_define_method(rb_klass, "rectangle!", RUBY_METHOD_FUNC(rb_rectangle_bang), -1); - rb_define_method(rb_klass, "circle", RUBY_METHOD_FUNC(rb_circle), -1); - rb_define_method(rb_klass, "circle!", RUBY_METHOD_FUNC(rb_circle_bang), -1); - rb_define_method(rb_klass, "ellipse", RUBY_METHOD_FUNC(rb_ellipse), -1); - rb_define_method(rb_klass, "ellipse!", RUBY_METHOD_FUNC(rb_ellipse_bang), -1); - rb_define_method(rb_klass, "ellipse_box", RUBY_METHOD_FUNC(rb_ellipse_box), -1); - rb_define_method(rb_klass, "ellipse_box!", RUBY_METHOD_FUNC(rb_ellipse_box_bang), -1); - rb_define_method(rb_klass, "fill_poly", RUBY_METHOD_FUNC(rb_fill_poly), -1); - rb_define_method(rb_klass, "fill_poly!", RUBY_METHOD_FUNC(rb_fill_poly_bang), -1); - rb_define_method(rb_klass, "fill_convex_poly", RUBY_METHOD_FUNC(rb_fill_convex_poly), -1); - rb_define_method(rb_klass, "fill_convex_poly!", RUBY_METHOD_FUNC(rb_fill_convex_poly_bang), -1); - rb_define_method(rb_klass, "poly_line", RUBY_METHOD_FUNC(rb_poly_line), -1); - rb_define_method(rb_klass, "poly_line!", RUBY_METHOD_FUNC(rb_poly_line_bang), -1); - rb_define_method(rb_klass, "put_text", RUBY_METHOD_FUNC(rb_put_text), -1); - rb_define_method(rb_klass, "put_text!", RUBY_METHOD_FUNC(rb_put_text_bang), -1); - - rb_define_method(rb_klass, "dft", RUBY_METHOD_FUNC(rb_dft), -1); - rb_define_method(rb_klass, "dct", RUBY_METHOD_FUNC(rb_dct), -1); - - rb_define_method(rb_klass, "sobel", RUBY_METHOD_FUNC(rb_sobel), -1); - rb_define_method(rb_klass, "laplace", RUBY_METHOD_FUNC(rb_laplace), -1); - rb_define_method(rb_klass, "canny", RUBY_METHOD_FUNC(rb_canny), -1); - rb_define_method(rb_klass, "pre_corner_detect", RUBY_METHOD_FUNC(rb_pre_corner_detect), -1); - rb_define_method(rb_klass, "corner_eigenvv", RUBY_METHOD_FUNC(rb_corner_eigenvv), -1); - rb_define_method(rb_klass, "corner_min_eigen_val", RUBY_METHOD_FUNC(rb_corner_min_eigen_val), -1); - rb_define_method(rb_klass, "corner_harris", RUBY_METHOD_FUNC(rb_corner_harris), -1); - rb_define_private_method(rb_klass, "__find_corner_sub_pix", RUBY_METHOD_FUNC(rbi_find_corner_sub_pix), -1); - rb_define_method(rb_klass, "good_features_to_track", RUBY_METHOD_FUNC(rb_good_features_to_track), -1); - - rb_define_method(rb_klass, "sample_line", RUBY_METHOD_FUNC(rb_sample_line), 2); - rb_define_method(rb_klass, "rect_sub_pix", RUBY_METHOD_FUNC(rb_rect_sub_pix), 2); - rb_define_method(rb_klass, "quadrangle_sub_pix", RUBY_METHOD_FUNC(rb_quadrangle_sub_pix), 2); - rb_define_method(rb_klass, "resize", RUBY_METHOD_FUNC(rb_resize), -1); - rb_define_method(rb_klass, "warp_affine", RUBY_METHOD_FUNC(rb_warp_affine), -1); - rb_define_singleton_method(rb_klass, "rotation", RUBY_METHOD_FUNC(rb_rotation), 3); - rb_define_method(rb_klass, "warp_perspective", RUBY_METHOD_FUNC(rb_warp_perspective), -1); - //rb_define_method(rb_klass, "get_perspective_transform", RUBY_METHOD_FUNC(rb_get_perspective_transform), -1); - //rb_define_alias(rb_klass, "warp_perspective_q_matrix", "get_perspective_transform"); - rb_define_method(rb_klass, "remap", RUBY_METHOD_FUNC(rb_remap), -1); - //rb_define_method(rb_klass, "log_polar", RUBY_METHOD_FUNC(rb_log_polar), -1); - - rb_define_method(rb_klass, "erode", RUBY_METHOD_FUNC(rb_erode), -1); - rb_define_method(rb_klass, "erode!", RUBY_METHOD_FUNC(rb_erode_bang), -1); - rb_define_method(rb_klass, "dilate", RUBY_METHOD_FUNC(rb_dilate), -1); - rb_define_method(rb_klass, "dilate!", RUBY_METHOD_FUNC(rb_dilate_bang), -1); - rb_define_method(rb_klass, "morphology_open", RUBY_METHOD_FUNC(rb_morphology_open), -1); - rb_define_method(rb_klass, "morphology_close", RUBY_METHOD_FUNC(rb_morphology_close), -1); - rb_define_method(rb_klass, "morphology_gradient", RUBY_METHOD_FUNC(rb_morphology_gradient), -1); - rb_define_method(rb_klass, "morphology_tophat", RUBY_METHOD_FUNC(rb_morphology_tophat), -1); - rb_define_method(rb_klass, "morphology_blackhat", RUBY_METHOD_FUNC(rb_morphology_blackhat), -1); - - rb_define_method(rb_klass, "smooth_blur_no_scale", RUBY_METHOD_FUNC(rb_smooth_blur_no_scale), -1); - rb_define_method(rb_klass, "smooth_blur", RUBY_METHOD_FUNC(rb_smooth_blur), -1); - rb_define_method(rb_klass, "smooth_gaussian", RUBY_METHOD_FUNC(rb_smooth_gaussian), -1); - rb_define_method(rb_klass, "smooth_median", RUBY_METHOD_FUNC(rb_smooth_median), -1); - rb_define_method(rb_klass, "smooth_bilateral", RUBY_METHOD_FUNC(rb_smooth_bilateral), -1); - rb_define_method(rb_klass, "filter2d", RUBY_METHOD_FUNC(rb_filter2d), -1); - rb_define_method(rb_klass, "copy_make_border_constant", RUBY_METHOD_FUNC(rb_copy_make_border_constant), -1); - rb_define_method(rb_klass, "copy_make_border_replicate", RUBY_METHOD_FUNC(rb_copy_make_border_replicate), -1); - rb_define_method(rb_klass, "integral", RUBY_METHOD_FUNC(rb_integral), -1); - rb_define_method(rb_klass, "threshold_binary", RUBY_METHOD_FUNC(rb_threshold_binary), -1); - rb_define_method(rb_klass, "threshold_binary_inverse", RUBY_METHOD_FUNC(rb_threshold_binary_inverse), -1); - rb_define_method(rb_klass, "threshold_trunc", RUBY_METHOD_FUNC(rb_threshold_trunc), -1); - rb_define_method(rb_klass, "threshold_to_zero", RUBY_METHOD_FUNC(rb_threshold_to_zero), -1); - rb_define_method(rb_klass, "threshold_to_zero_inverse", RUBY_METHOD_FUNC(rb_threshold_to_zero_inverse), -1); - - rb_define_method(rb_klass, "pyr_down", RUBY_METHOD_FUNC(rb_pyr_down), -1); - rb_define_method(rb_klass, "pyr_up", RUBY_METHOD_FUNC(rb_pyr_up), -1); - - rb_define_method(rb_klass, "flood_fill", RUBY_METHOD_FUNC(rb_flood_fill), -1); - rb_define_method(rb_klass, "flood_fill!", RUBY_METHOD_FUNC(rb_flood_fill_bang), -1); - rb_define_method(rb_klass, "find_contours", RUBY_METHOD_FUNC(rb_find_contours), -1); - rb_define_method(rb_klass, "find_contours!", RUBY_METHOD_FUNC(rb_find_contours_bang), -1); - rb_define_method(rb_klass, "pyr_segmentation", RUBY_METHOD_FUNC(rb_pyr_segmentation), -1); - rb_define_method(rb_klass, "pyr_mean_shift_filtering", RUBY_METHOD_FUNC(rb_pyr_mean_shift_filtering), -1); - rb_define_method(rb_klass, "watershed", RUBY_METHOD_FUNC(rb_watershed), 0); - - rb_define_method(rb_klass, "moments", RUBY_METHOD_FUNC(rb_moments), -1); - - rb_define_method(rb_klass, "hough_lines_standard", RUBY_METHOD_FUNC(rb_hough_lines_standard), -1); - rb_define_method(rb_klass, "hough_lines_probabilistic", RUBY_METHOD_FUNC(rb_hough_lines_probabilistic), -1); - rb_define_method(rb_klass, "hough_lines_multi_scale", RUBY_METHOD_FUNC(rb_hough_lines_multi_scale), -1); - rb_define_method(rb_klass, "hough_circles_gradient", RUBY_METHOD_FUNC(rb_hough_circles_gradient), -1); - //rb_define_method(rb_klass, "dist_transform", RUBY_METHOD_FUNC(rb_dist_transform), -1); - - rb_define_method(rb_klass, "inpaint_ns", RUBY_METHOD_FUNC(rb_inpaint_ns), 2); - rb_define_method(rb_klass, "inpaint_telea", RUBY_METHOD_FUNC(rb_inpaint_telea), 2); - - rb_define_method(rb_klass, "equalize_hist", RUBY_METHOD_FUNC(rb_equalize_hist), 0); - rb_define_method(rb_klass, "match_template", RUBY_METHOD_FUNC(rb_match_template), -1); - rb_define_method(rb_klass, "match_shapes_i1", RUBY_METHOD_FUNC(rb_match_shapes_i1), -1); - rb_define_method(rb_klass, "match_shapes_i2", RUBY_METHOD_FUNC(rb_match_shapes_i2), -1); - rb_define_method(rb_klass, "match_shapes_i3", RUBY_METHOD_FUNC(rb_match_shapes_i3), -1); - - rb_define_method(rb_klass, "mean_shift", RUBY_METHOD_FUNC(rb_mean_shift), 2); - rb_define_method(rb_klass, "cam_shift", RUBY_METHOD_FUNC(rb_cam_shift), 2); - rb_define_method(rb_klass, "snake_image", RUBY_METHOD_FUNC(rb_snake_image), -1); - - rb_define_method(rb_klass, "optical_flow_hs", RUBY_METHOD_FUNC(rb_optical_flow_hs), -1); - rb_define_method(rb_klass, "optical_flow_lk", RUBY_METHOD_FUNC(rb_optical_flow_lk), -1); - rb_define_method(rb_klass, "optical_flow_bm", RUBY_METHOD_FUNC(rb_optical_flow_bm), -1); - - rb_define_singleton_method(rb_klass, "find_fundamental_mat_7point", RUBY_METHOD_FUNC(rb_find_fundamental_mat_7point), -1); - rb_define_singleton_method(rb_klass, "find_fundamental_mat_8point", RUBY_METHOD_FUNC(rb_find_fundamental_mat_8point), -1); - rb_define_singleton_method(rb_klass, "find_fundamental_mat_ransac", RUBY_METHOD_FUNC(rb_find_fundamental_mat_ransac), -1); - rb_define_singleton_method(rb_klass, "find_fundamental_mat_lmeds", RUBY_METHOD_FUNC(rb_find_fundamental_mat_lmeds), -1); - rb_define_singleton_method(rb_klass, "compute_correspond_epilines", RUBY_METHOD_FUNC(rb_compute_correspond_epilines), 3); - - rb_define_method(rb_klass, "save_image", RUBY_METHOD_FUNC(rb_save_image), 1); -} - -VALUE -rb_allocate(VALUE klass) -{ - return OPENCV_OBJECT(klass, 0); -} - -/* - * call-seq: - * CvMat.new(row, col[, depth = CV_8U][, channel = 3]) -> cvmat - * - * Create col * row matrix. Each element set 0. - * - * Each element possigle range is set by depth. Default is unsigned 8bit. - * - * Number of channel is set by channel. channel should be 1..4. - * - */ -VALUE -rb_initialize(int argc, VALUE *argv, VALUE self) -{ - VALUE row, column, depth, channel; - rb_scan_args(argc, argv, "22", &row, &column, &depth, &channel); - DATA_PTR(self) = cvCreateMat(FIX2INT(row), FIX2INT(column), - CV_MAKETYPE(CVMETHOD("DEPTH", depth, CV_8U), argc < 4 ? 3 : FIX2INT(channel))); - return self; -} - -/* - * nodoc - */ -VALUE -rb_method_missing(int argc, VALUE *argv, VALUE self) -{ - /* - const char *to_str = "\\Ato_(\\w+)"; - VALUE name, args, str[3], method; - rb_scan_args(argc, argv, "1*", &name, &args); - if (RARRAY(args)->len != 0) - return rb_call_super(argc, argv); - if(rb_reg_match(rb_reg_new(to_str, strlen(to_str), 0), rb_funcall(name, rb_intern("to_s"), 0)) == Qnil) - return rb_call_super(argc, argv); - str[0] = rb_str_new2("%s2%s"); - str[1] = rb_color_model(self); - str[2] = rb_reg_nth_match(1, rb_backref_get()); - method = rb_f_sprintf(3, str); - if (rb_respond_to(rb_module_opencv(), rb_intern(StringValuePtr(method)))) - return rb_funcall(rb_module_opencv(), rb_intern(StringValuePtr(method)), 1, self); - return rb_call_super(argc, argv); - */ - VALUE name, args, method; - rb_scan_args(argc, argv, "1*", &name, &args); - method = rb_funcall(name, rb_intern("to_s"), 0); - if (RARRAY(args)->len != 0 || !rb_respond_to(rb_module_opencv(), rb_intern(StringValuePtr(method)))) - return rb_call_super(argc, argv); - return rb_funcall(rb_module_opencv(), rb_intern(StringValuePtr(method)), 1, self); -} - -/* - * call-seq: - * to_s -> string - * - * Return following string. - * m = CvMat.new(100, 100, :cv8u, 3) - * m.to_s # => - */ -VALUE -rb_to_s(VALUE self) -{ - const int i = 6; - VALUE str[i]; - str[0] = rb_str_new2("<%s:%dx%d,depth=%s,channel=%d>"); - str[1] = rb_str_new2(rb_class2name(CLASS_OF(self))); - str[2] = rb_width(self); - str[3] = rb_height(self); - str[4] = rb_depth(self); - str[5] = rb_channel(self); - return rb_f_sprintf(i, str); -} - -/* - * call-seq: - * has_parent? -> true or false - * - * Return true if this matrix has parent object, otherwise false. - */ -VALUE -rb_has_parent_q(VALUE self) -{ - return lookup_root_object(CVMAT(self)) ? Qtrue : Qfalse; -} - -/* - * call-seq: - * parent -> obj or nil - * - * Return root object that refer this object. - */ -VALUE -rb_parent(VALUE self) -{ - VALUE root = lookup_root_object(CVMAT(self)); - return root ? root : Qnil; -} - -/* - * call-seq: - * inside?(obj) -> true or false - * - * - */ -VALUE -rb_inside_q(VALUE self, VALUE object) -{ - if (cCvPoint::rb_compatible_q(cCvPoint::rb_class(), object)) { - CvMat *mat = CVMAT(self); - int x = NUM2INT(rb_funcall(object, rb_intern("x"), 0)); - int y = NUM2INT(rb_funcall(object, rb_intern("y"), 0)); - if (cCvRect::rb_compatible_q(cCvRect::rb_class(), object)) { - int width = NUM2INT(rb_funcall(object, rb_intern("width"), 0)); - int height = NUM2INT(rb_funcall(object, rb_intern("height"), 0)); - return x >= 0 && y >= 0 && x < mat->width && x + width < mat->width && y < mat->height && y + height < mat->height ? Qtrue : Qfalse; - } else { - return x >= 0 && y >= 0 && x < mat->width && y < mat->height ? Qtrue : Qfalse; - } - } - rb_raise(rb_eArgError, "argument 1 should have method \"x\", \"y\""); -} - -/* - * call-seq: - * to_IplConvKernel -> iplconvkernel - * - * Create IplConvKernel from this matrix. - */ -VALUE -rb_to_IplConvKernel(VALUE self, VALUE anchor) -{ - CvMat *src = CVMAT(self); - CvPoint p = VALUE_TO_CVPOINT(anchor); - IplConvKernel *kernel = cvCreateStructuringElementEx(src->cols, src->rows, p.x, p.y, CV_SHAPE_CUSTOM, src->data.i); - return DEPEND_OBJECT(cIplConvKernel::rb_class(), kernel, self); -} - -/* - * call-seq: - * create_mask -> cvmat(single-channel 8bit unsinged image) - * - * Create single-channel 8bit unsinged image that filled 0. - */ -VALUE -rb_create_mask(VALUE self) -{ - VALUE mask = cCvMat::new_object(cvGetSize(CVARR(self)), CV_8UC1); - cvZero(CVARR(self)); - return mask; -} - -/* - * call-seq: - * width -> int - * - * Return number of columns. - */ -VALUE -rb_width(VALUE self) -{ - return INT2FIX(CVMAT(self)->width); -} - -/* - * call-seq: - * height -> int - * - * Return number of rows. - */ -VALUE -rb_height(VALUE self) -{ - return INT2FIX(CVMAT(self)->height); -} - -/* - * call-seq: - * depth -> symbol - * - * Return depth symbol. (see OpenCV::DEPTH) - */ -VALUE -rb_depth(VALUE self) -{ - return rb_hash_aref(rb_funcall(rb_const_get(rb_module_opencv(), rb_intern("DEPTH")), rb_intern("invert"), 0), INT2FIX(CV_MAT_DEPTH(CVMAT(self)->type))); -} - -/* - * call-seq: - * channel -> int (1 < channel < 4) - * - * Return number of channel. - */ -VALUE -rb_channel(VALUE self) -{ - return INT2FIX(CV_MAT_CN(CVMAT(self)->type)); -} - -/* - * call-seq: - * data -> binary (by String class) - * - * Return raw data of matrix. - */ -VALUE -rb_data(VALUE self) -{ - IplImage *image = IPLIMAGE(self); - return rb_str_new((char *)image->imageData, image->imageSize); -} - -/* - * call-seq: - * clone -> cvmat - * - * Clone matrix. The parent and child relation is not succeeded. - * Instance-specific method is succeeded. - * - * module M - * def example - * true - * end - * end - * - * mat.extend M - * mat.example #=> true - * clone = mat.clone - * clone.example #=> true - * copy = mat.copy - * copy.example #=> raise NoMethodError - */ -VALUE -rb_clone(VALUE self) -{ - VALUE clone = rb_obj_clone(self); - DATA_PTR(clone) = cvClone(CVARR(self)); - return clone; -} - -/* - * call-seq: - * copy() -> cvmat - * copy(mat) -> mat - * copy(val) -> array(include cvmat) - * - * Copy matrix. The parent and child relation is not succeeded. - * Instance-specific method is *NOT* succeeded. see also #clone. - * - * There are 3 kind behavior depending on the argument. - * - * copy() - * Return one copied matrix. - * copy(mat) - * Copy own elements to target matrix. Return nil. - * Size (or ROI) and channel and depth should be match. - * If own width or height does not match target matrix, raise CvUnmatchedSizes - * If own channel or depth does not match target matrix, raise CvUnmatchedFormats - * copy(val) - * The amounts of the specified number are copied. Return Array with copies. - * If you give the 0 or negative value. Return nil. - * mat.copy(3) #=> [mat1, mat2, mat3] - * mat.copy(-1) #=> nil - * - * When not apply to any, raise ArgumentError - */ -VALUE -rb_copy(int argc, VALUE *argv, VALUE self) -{ - VALUE value, copied; - CvMat *src = CVMAT(self); - rb_scan_args(argc, argv, "01", &value); - if (argc == 0) { - CvSize size = cvGetSize(src); - copied = new_object(cvGetSize(src), cvGetElemType(src)); - cvCopy(src, CVMAT(copied)); - return copied; - }else{ - if (rb_obj_is_kind_of(value, rb_klass)) { - cvCopy(src, CVMAT(value)); - return Qnil; - }else if (rb_obj_is_kind_of(value, rb_cFixnum)) { - int n = FIX2INT(value); - if (n > 0) { - copied = rb_ary_new2(n); - for (int i = 0; i < n; i++) { - rb_ary_store(copied, i, new_object(src->rows, src->cols, cvGetElemType(src))); - } - return copied; - }else{ - return Qnil; - } - }else - rb_raise(rb_eArgError, ""); - } -} - -VALUE -copy(VALUE mat) -{ - CvMat *src = CVMAT(mat); - VALUE copied = new_object(cvGetSize(src), cvGetElemType(src)); - cvCopy(src, CVMAT(copied)); - return copied; -} - - -/* - * call-seq: - * to_8u -> cvmat(depth = CV_8U) - * - * Return the new matrix that elements is converted to unsigned 8bit. - */ -VALUE -rb_to_8u(VALUE self) -{ - CvMat *src = CVMAT(self); - VALUE dest = new_object(src->rows, src->cols, CV_MAKETYPE(CV_8U, CV_MAT_CN(src->type))); - cvConvert(src, CVMAT(dest)); - return dest; -} - -/* - * call-seq: - * to_8s -> cvmat(depth = CV_8S) - * - * Return the new matrix that elements is converted to signed 8bit. - */ -VALUE -rb_to_8s(VALUE self) -{ - CvMat *src = CVMAT(self); - VALUE dest = new_object(src->rows, src->cols, CV_MAKETYPE(CV_8S, CV_MAT_CN(src->type))); - cvConvert(src, CVMAT(dest)); - return dest; -} - -/* - * call-seq: - * to_16u -> cvmat(depth = CV_16U) - * - * Return the new matrix that elements is converted to unsigned 16bit. - */ -VALUE rb_to_16u(VALUE self) -{ - CvMat *src = CVMAT(self); - VALUE dest = new_object(src->rows, src->cols, CV_MAKETYPE(CV_16U, CV_MAT_CN(src->type))); - cvConvert(src, CVMAT(dest)); - return dest; -} - -/* - * call-seq: - * to_16s -> cvmat(depth = CV_16s) - * - * Return the new matrix that elements is converted to signed 16bit. - */ -VALUE -rb_to_16s(VALUE self) -{ - CvMat *src = CVMAT(self); - VALUE dest = new_object(src->rows, src->cols, CV_MAKETYPE(CV_16U, CV_MAT_CN(src->type))); - cvConvert(src, CVMAT(dest)); - return dest; -} - -/* - * call-seq: - * to_32s -> cvmat(depth = CV_32S) - * - * Return the new matrix that elements is converted to signed 32bit. - */ -VALUE -rb_to_32s(VALUE self) -{ - CvMat *src = CVMAT(self); - VALUE dest = new_object(src->rows, src->cols, CV_MAKETYPE(CV_32S, CV_MAT_CN(src->type))); - cvConvert(src, CVMAT(dest)); - return dest; -} - -/* - * call-seq: - * to_32f -> cvmat(depth = CV_32F) - * - * Return the new matrix that elements is converted to 32bit floating-point. - */ -VALUE -rb_to_32f(VALUE self) -{ - CvMat *src = CVMAT(self); - VALUE dest = new_object(src->rows, src->cols, CV_MAKETYPE(CV_32F, CV_MAT_CN(src->type))); - cvConvert(src, CVMAT(dest)); - return dest; -} - -/* - * call-seq: - * to_64F -> cvmat(depth = CV_64F) - * - * Return the new matrix that elements is converted to 64bit floating-point. - */ -VALUE -rb_to_64f(VALUE self) -{ - CvMat *src = CVMAT(self); - VALUE dest = new_object(src->rows, src->cols, CV_MAKETYPE(CV_64F, CV_MAT_CN(src->type))); - cvConvert(src, CVMAT(dest)); - return dest; -} - -/* - * call-seq: - * vector? -> true or false - * - * If #width or #height is 1, return true. Otherwise return false. - */ -VALUE -rb_vector_q(VALUE self) -{ - CvMat *mat = CVMAT(self); - return (mat->width == 1|| mat->height == 1) ? Qtrue : Qfalse; -} - -/* - * call-seq: - * square? -> true or false - * - * If #width == #height return true. Otherwise return false. - */ -VALUE -rb_square_q(VALUE self) -{ - CvMat *mat = CVMAT(self); - return mat->width == mat->height ? Qtrue : Qfalse; -} - -/************************************************************ - cxcore function -************************************************************/ -/* - * Return CvMat object with reference to caller-object. - * - * src = CvMat.new(10, 10) - * src.has_parent? #=> false - * src.parent #=> nil - * mat = src.to_CvMat - * mat.has_parent? #=> true - * mat.parent #=> CvMat object "src" - * - * This case, 'src' is root-object. and 'mat' is child-object refer to 'src'. - * src <=refer= mat - * In C, 'src->data' and 'mat->data' is common. Therefore, they cause the change each other. - * object 'src' don't GC. - */ -VALUE -rb_to_CvMat(VALUE self) -{ - return DEPEND_OBJECT(rb_klass, cvGetMat(CVARR(self), CVALLOC(CvMat)), self); -} - -/* - * call-seq: - * sub_rect(rect) -> cvmat - * sub_rect(topleft, size) -> cvmat - * sub_rect(x, y, width, height) -> cvmat - * - * Return parts of self as CvMat. - * - * p or x,y mean top-left coordinate. - * size or width,height is size. - * - * link:../images/CvMat_sub_rect.png - */ -VALUE -rb_sub_rect(VALUE self, VALUE args) -{ - CvRect area; - CvPoint topleft; - CvSize size; - switch(RARRAY(args)->len) { - case 1: - area = VALUE_TO_CVRECT(RARRAY(args)->ptr[0]); - break; - case 2: - topleft = VALUE_TO_CVPOINT(RARRAY(args)->ptr[0]); - size = VALUE_TO_CVSIZE(RARRAY(args)->ptr[1]); - area.x = topleft.x; - area.y = topleft.y; - area.width = size.width; - area.height = size.height; - break; - case 4: - area.x = NUM2INT(RARRAY(args)->ptr[0]); - area.y = NUM2INT(RARRAY(args)->ptr[1]); - area.width = NUM2INT(RARRAY(args)->ptr[2]); - area.height = NUM2INT(RARRAY(args)->ptr[3]); - break; - default: - rb_raise(rb_eArgError, "wrong number of arguments (%d of 1 or 2 or 4)", RARRAY(args)->len); - } - return DEPEND_OBJECT(rb_klass, - cvGetSubRect(CVARR(self), CVALLOC(CvMat), area), - self); -} - -/* - * call-seq: - * slice_width(n) - * - * The matrix is divided into n piece by the width. - * If it cannot be just divided, warning is displayed. - * - * e.g. - * m = OpenCV::CvMat.new(10, 10) #=> size 10x10 matrix - * ml, mr = m.slice_width(2) #=> 5x10 and 5x10 matrix - * - * ml, mm, mr = m.sclice_width(3)#=> 3x10 3x10 3x10 matrix - * warning : width does not div correctly. - */ -VALUE -rb_slice_width(VALUE self, VALUE num) -{ - int n = NUM2INT(num); - if (n < 1) {rb_raise(rb_eArgError, "number of piece should be > 0");} - CvSize size = cvGetSize(CVARR(self)); - if (size.width % n != 0) {rb_warn("width does not div correctly.");} - int div_x = size.width / n; - VALUE ary = rb_ary_new2(n); - for (int i = 0; i < n; i++) { - CvRect rect = {div_x * i, 0, div_x, size.height}; - rb_ary_push(ary, DEPEND_OBJECT(rb_klass, cvGetSubRect(CVARR(self), CVALLOC(CvMat), rect), self)); - } - return ary; -} - -/* - * call-seq: - * slice_height(n) - * - * The matrix is divided into n piece by the height. - * If it cannot be just divided, warning is displayed. - * - * see also #slice_width. - */ -VALUE -rb_slice_height(VALUE self, VALUE num) -{ - int n = NUM2INT(num); - if (n < 1) {rb_raise(rb_eArgError, "number of piece should be > 0");} - CvSize size = cvGetSize(CVARR(self)); - if (size.height % n != 0) {rb_warn("height does not div correctly.");} - int div_y = size.height / n; - VALUE ary = rb_ary_new2(n); - for (int i = 0; i < n; i++) { - CvRect rect = {0, div_y * i, size.width, div_y}; - rb_ary_push(ary, DEPEND_OBJECT(rb_klass, cvGetSubRect(CVARR(self), CVALLOC(CvMat), rect), self)); - } - return ary; -} - -/* - * call-seq: - * row(n) -> Return row - * row(n1, n2, ...) -> Return Array of row - * - * Return row(or rows) of matrix. - * argument should be Fixnum or CvSlice compatible object. - */ -VALUE -rb_row(VALUE self, VALUE args) -{ - int len = RARRAY(args)->len; - if (len < 1) {rb_raise(rb_eArgError, "wrong number of argument.(more than 1)");} - VALUE ary = rb_ary_new2(len); - for (int i = 0; i < len; i++) { - VALUE value = rb_ary_entry(args, i); - if (FIXNUM_P(value)) { - rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, cvGetRow(CVARR(self), CVALLOC(CvMat), FIX2INT(value)), self)); - }else{ - CvSlice slice = VALUE_TO_CVSLICE(value); - rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, cvGetRows(CVARR(self), CVALLOC(CvMat), slice.start_index, slice.end_index), self)); - } - } - return RARRAY(ary)->len > 1 ? ary : rb_ary_entry(ary, 0); -} - -/* - * call-seq: - * col(n) -> Return column - * col(n1, n2, ...) -> Return Array of columns - * - * Return column(or columns) of matrix. - * argument should be Fixnum or CvSlice compatible object. - */ -VALUE -rb_col(VALUE self, VALUE args) -{ - int len = RARRAY(args)->len; - if (len < 1) {rb_raise(rb_eArgError, "wrong number of argument.(more than 1)");} - VALUE ary = rb_ary_new2(len); - for (int i = 0; i < len; i++) { - VALUE value = rb_ary_entry(args, i); - if (FIXNUM_P(value)) { - rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, cvGetCol(CVARR(self), CVALLOC(CvMat), FIX2INT(value)), self)); - }else{ - CvSlice slice = VALUE_TO_CVSLICE(value); - rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, cvGetCols(CVARR(self), CVALLOC(CvMat), slice.start_index, slice.end_index), self)); - } - } - return RARRAY(ary)->len > 1 ? ary : rb_ary_entry(ary, 0); -} - -/* - * call-seq: - * each_row{|row| ... } -> self - * - * Calls block once for each row in self, passing that element as a parameter. - * - * see also CvMat#each_col - */ -VALUE -rb_each_row(VALUE self) -{ - int rows = CVMAT(self)->rows; - for (int i = 0; i < rows; i++) { - rb_yield(DEPEND_OBJECT(rb_klass, cvGetRow(CVARR(self), CVALLOC(CvMat), i), self)); - } - return self; -} - -/* - * call-seq: - * each_col{|col| ... } -> self - * - * Calls block once for each column in self, passing that element as a parameter. - * - * see also CvMat#each_row - */ -VALUE -rb_each_col(VALUE self) -{ - int cols = CVMAT(self)->cols; - for (int i = 0; i < cols; i++) { - rb_yield(DEPEND_OBJECT(rb_klass, cvGetCol(CVARR(self), CVALLOC(CvMat), i), self)); - } - return self; -} - -/* - * call-seq: - * diag([val = 0]) -> cvmat - * - * Return one of array diagonals. - * val is zeo corresponds to the main diagonal, -1 corresponds to the diagonal above the main etc, 1 corresponds to the diagonal below the main etc. - * - */ -VALUE -rb_diag(int argc, VALUE *argv, VALUE self) -{ - VALUE val; - if (rb_scan_args(argc, argv, "01", &val) < 1) { - val = INT2FIX(0); - } - return DEPEND_OBJECT(rb_klass, cvGetDiag(CVARR(self), CVALLOC(CvMat), NUM2INT(val)), self); -} - -/* - * call-seq: - * size -> cvsize - * - * Return size by CvSize - */ -VALUE -rb_size(VALUE self) -{ - return cCvSize::new_object(cvGetSize(CVARR(self))); -} - -/* - VALUE rb_elem_type(VALUE self) { - return INT2FIX(cvGetElemType(CVARR(self))); - } -*/ - -/* - * call-seq: - * dims -> array(int, int, ...) - * - * Return number of array dimensions and their sizes or the size of particular dimension. - * In case of CvMat it always returns 2 regardless of number of matrix rows. - */ -VALUE -rb_dims(VALUE self) -{ - int size[CV_MAX_DIM]; - int dims = cvGetDims(CVARR(self), size); - VALUE ary = rb_ary_new2(dims); - for (int i = 0; i < dims; i++) { - rb_ary_store(ary, i, INT2FIX(size[i])); - } - return ary; -} - -/* - * call-seq: - * dim_size(index) -> int - * - * Return number of dimension. - * almost same as CvMat#dims[index]. - * If the dimension specified with index doesn't exist, CvStatusOutOfRange raise. - */ -VALUE -rb_dim_size(VALUE self, VALUE index) -{ - return INT2FIX(cvGetDimSize(CVARR(self), FIX2INT(index))); -} - -/* - * call-seq: - * [idx1[,idx2]...] - * - * Return value of the particular array element as CvScalar. - */ -VALUE -rb_aref(VALUE self, VALUE args) -{ - int index[CV_MAX_DIM]; - for (int i = 0; i < RARRAY(args)->len; i++) { - index[i] = NUM2INT(rb_ary_entry(args, i)); - } - CvScalar scalar = cvScalarAll(0); - switch(RARRAY(args)->len) { - case 1: - scalar = cvGet1D(CVARR(self), index[0]); - break; - case 2: - scalar = cvGet2D(CVARR(self), index[1], index[0]); - break; - case 3: - scalar = cvGet3D(CVARR(self), index[2], index[1], index[0]); - break; - default: - scalar = cvGetND(CVARR(self), index); - } - return cCvScalar::new_object(scalar); -} - -/* - * call-seq: - * [idx1[,idx2]...] = value - * - * Set value of the particular array element to value. - * value should be CvScalar. - */ -VALUE -rb_aset(VALUE self, VALUE args) -{ - CvScalar scalar = VALUE_TO_CVSCALAR(rb_ary_pop(args)); - int index[CV_MAX_DIM]; - for (int i = 0; i < RARRAY(args)->len; i++) { - index[i] = NUM2INT(rb_ary_entry(args, i)); - } - switch(RARRAY(args)->len) { - case 1: - cvSet1D(CVARR(self), index[0], scalar); - break; - case 2: - cvSet2D(CVARR(self), index[1], index[0], scalar); - break; - case 3: - cvSet3D(CVARR(self), index[2], index[1], index[0], scalar); - break; - default: - cvSetND(CVARR(self), index, scalar); - } - return self; -} - -/* - * call-seq: - * fill(value[, mask]) -> cvmat - * - * Return CvMat copied value to every selected element. value should be CvScalar or compatible object. - * self[I] = value if mask(I)!=0 - * - * note: This method support ROI on IplImage class. but COI not support. COI should not be set. - * image = IplImage.new(10, 20) #=> create 3 channel image. - * image.coi = 1 #=> set COI - * image.fill(CvScalar.new(10, 20, 30)) #=> raise CvBadCOI error. - */ -VALUE -rb_fill(int argc, VALUE *argv, VALUE self) -{ - return rb_fill_bang(argc, argv, copy(self)); -} - -/* - * call-seq: - * fill!(value[, mask]) -> self - * - * Copie value to every selected element. - * self[I] = value if mask(I)!=0 - * - * see also #fill. - */ -VALUE -rb_fill_bang(int argc, VALUE *argv, VALUE self) -{ - VALUE value, mask; - rb_scan_args(argc, argv, "11", &value, &mask); - cvSet(CVARR(self), VALUE_TO_CVSCALAR(value), MASK(mask)); - return self; -} - -/* - * call-seq: - * save_image(filename) -> self - * - * Saves an image to file. The image format is chosen depending on the filename extension. - * Only 8bit single-channel or 3-channel(with 'BGR' channel order) image can be saved. - * - * e.g. - * image = OpenCV::CvMat.new(10, 10, CV_8U, 3) - * image.save_image("image.jpg") #=> save as JPEG format - * image.save_image("image.png") #=> save as PNG format - */ -VALUE -rb_save_image(VALUE self, VALUE filename) -{ - Check_Type(filename, T_STRING); - cvSaveImage(StringValueCStr(filename), CVARR(self)); - return self; -} - -/* - * call-seq: - * clear -> cvmat - * - * Return new matrix all element-value cleared. - */ -VALUE -rb_clear(VALUE self) -{ - return rb_clear_bang(copy(self)); -} - -/* - * call-seq: - * clear! -> self - * - * Clear all element-value. Return self. - */ -VALUE -rb_clear_bang(VALUE self) -{ - cvSetZero(CVARR(self)); - return self; -} - -/* - * call-seq: - * identity([val = [1]]) -> cvmat - * - * Return initializes scaled identity matrix. - * val should be CvScalar. - * - * arr(i, j) = val if i = j, 0 otherwise - */ -VALUE -rb_set_identity(int argc, VALUE *argv, VALUE self) -{ - return rb_set_identity_bang(argc, argv, copy(self)); -} - -/* - * call-seq: - * identity!([val = [1]]) -> self - * - * Initialize scaled identity matrix. - * val should be CvScalar. - * - * arr(i, j) = val if i = j, 0 otherwise - */ -VALUE -rb_set_identity_bang(int argc, VALUE *argv, VALUE self) -{ - VALUE val; - CvScalar value; - if (rb_scan_args(argc, argv, "01", &val) < 1) { - value = cvRealScalar(1); - }else{ - value = VALUE_TO_CVSCALAR(val); - } - cvSetIdentity(CVARR(self), value); - return self; -} - -/* - * call-seq: - * range(start, end) -> cvmat - * - * Create and return filled matrix with given range of numbers. - * - * see range! - */ -VALUE -rb_range(int argc, VALUE *argv, VALUE self) -{ - return rb_range_bang(argc, argv, copy(self)); -} - -/* - * call-seq: - * range!(start, end) -> self - * - * Fills matrix with given range of numbers. - * - * initializes the matrix as following: - * arr(i,j)=(end-start)*(i*cols(arr)+j)/(cols(arr)*rows(arr)) - * For example, the following code will initilize 1D vector with subsequent integer numbers. - * m = CvMat.new(1, 10, :cv32s) - * m.range!(0, m.cols); // m will be initialized as [0,1,2,3,4,5,6,7,8,9] - */ -VALUE -rb_range_bang(int argc, VALUE *argv, VALUE self) -{ - VALUE start, end; - rb_scan_args(argc, argv, "20", &start, &end); - cvRange(CVARR(self), NUM2DBL(start), NUM2DBL(end)); - return self; -} - - - - -/* - * call-seq: - * reshape([:rows => num][, :channel => cn]) -> cvmat(refer self) - * - * Change shape of matrix/image without copying data. - * - * e.g. - * mat = CvMat.new(3, 3, CV_8U, 3) #=> 3x3 3-channel matrix - * vec = mat.reshape(:rows => 1) #=> 1x9 3-channel matrix - * ch1 = mat.reshape(:channel => 1) #=> 9x9 1-channel matrix - */ -VALUE -rb_reshape(VALUE self, VALUE hash) -{ - if (TYPE(hash) != T_HASH) - rb_raise(rb_eTypeError, "argument should be Hash that contaion key (:row, :channel)."); - VALUE channel = rb_hash_aref(hash, ID2SYM(rb_intern("channel"))); - VALUE rows = rb_hash_aref(hash, ID2SYM(rb_intern("rows"))); - return DEPEND_OBJECT(rb_klass, cvReshape(CVARR(self), CVALLOC(CvMat), NIL_P(rows) ? 0 : FIX2INT(rows), NIL_P(channel) ? 0 : FIX2INT(channel)), self); -} - -/* - * call-seq: - * repeat(mat) -> cvmat - * - * Tiled mat by self. - */ -VALUE -rb_repeat(VALUE self, VALUE object) -{ - if (rb_obj_is_kind_of(object, rb_class())) - rb_raise(rb_eTypeError, "argument should be CvMat subclass."); - cvRepeat(CVARR(self), CVARR(object)); - return object; -} - -/* - * call-seq: - * flip(:x) -> cvmat - * flip(:y) -> cvmat - * flip -> -> cvmat - * - * Return new flipped 2D array. - * * flip(:x) - flip around horizontal - * * flip(:y) - flip around vertical - * * flip - flip around both axises - */ -VALUE -rb_flip(int argc, VALUE *argv, VALUE self) -{ - return rb_flip_bang(argc, argv, copy(self)); -} - -/* - * call-seq: - * flip!(:x) -> self - * flip!(:y) -> self - * flip! -> self - * - * Flip 2D array. Return self. - * - * see also CvMat#flip - */ -VALUE -rb_flip_bang(int argc, VALUE *argv, VALUE self) -{ - VALUE format; - int mode = -1; - if (rb_scan_args(argc, argv, "01", &format) > 0) { - if (rb_to_id(format) == rb_intern("x")) - mode = 1; - else if (rb_to_id(format) == rb_intern("y")) - mode = 0; - else - rb_warn("argument may be :x or :y"); - } - cvFlip(CVARR(self), NULL, mode); - return self; -} - -/* - * call-seq: - * split -> array(include cvmat) - * - * Divides multi-channel array into several single-chanel arrays. - * - * e.g. - * image = CvMat.new 640, 480, CV_8U, 3 #=> 3-channel image - * image.split #=> [image1, image2, image3] : each image have single-channel - * - * e.g. switch red <-> blue channel. - * image = IplImage.load "sample.bmp" - * i = image.split - * new_image = CvMat.merge i[2], i[1], i[0] - */ -VALUE -rb_split(VALUE self) -{ - int type = CVMAT(self)->type, depth = CV_MAT_DEPTH(type), channel = CV_MAT_CN(type); - CvSize size = cvGetSize(CVARR(self)); - CvMat *dest[] = {NULL, NULL, NULL, NULL}; - for (int i = 0; i < channel; i++) - dest[i] = cvCreateMat(size.height, size.width, CV_MAKETYPE(depth, 1)); - cvSplit(CVARR(self), dest[0], dest[1], dest[2], dest[3]); - VALUE ary = rb_ary_new2(channel); - for (int i = 0; i < channel; i++) - rb_ary_store(ary, i, OPENCV_OBJECT(rb_klass, dest[i])); - return ary; -} - -/* - * call-seq: - * CvMat.merge(mat1[,mat2][,mat3][,mat4]) -> cvmat - * - * Composes multi-channel array from several single-channel arrays. - * Each argument should be single-channel image(CvMat or subclass). - * All image should be same size and same depth. - * - * see also CvMat#split - */ -VALUE -rb_merge(VALUE klass, VALUE args) -{ - VALUE object, dest; - int len = RARRAY(args)->len; - if (!(len > 0) || len > CV_CN_MAX) { - rb_raise(rb_eArgError, "wrong number of argument (%d for 1..4)", len); - } - CvMat *src[] = {NULL, NULL, NULL, NULL}, *tmp = 0; - for (int i = 0; i < len; i++) { - if (rb_obj_is_kind_of((object = rb_ary_entry(args, i)), rb_klass)) { - src[i] = CVMAT(object); - if (CV_MAT_CN(src[i]->type) != 1) { - rb_raise(rb_eStandardError, "image should be single-channel CvMat."); - } - if (!tmp) - tmp = src[i]; - else{ - if (!CV_ARE_SIZES_EQ(tmp, src[i])) - rb_raise(rb_eStandardError, "image size should be same."); - if (!CV_ARE_DEPTHS_EQ(tmp, src[i])) - rb_raise(rb_eStandardError, "image depth should be same."); - } - }else if (NIL_P(object)) { - src[i] = NULL; - }else - rb_raise(rb_eTypeError, "argument should be CvMat or subclass of it."); - } - dest = new_object(cvGetSize(tmp), CV_MAKETYPE(CV_MAT_DEPTH(tmp->type), len)); - cvMerge(src[0], src[1], src[2], src[3], CVARR(dest)); - return dest; -} - -/* - * call-seq: - * CvMat.mix_channels(srcs,dests,from_to = {1 => 1, 2 => 2, 3 => 3, 4 => 4}) -> dests - */ -VALUE -rb_mix_channels(int argc, VALUE *argv, VALUE self) -{ - VALUE srcs, dests, from_to; - rb_scan_args(argc, argv, "21", &srcs, &dests, &from_to); - /* not yet */ - return Qnil; -} - -/* - * call-seq: - * rand_shuffle([seed = nil][,iter = 1]) - * - * Return filled the destination array with values from the look-up table. - * - * see rand_shuffle! - */ -VALUE -rb_rand_shuffle(int argc, VALUE *argv, VALUE self) -{ - return rb_rand_shuffle_bang(argc, argv, copy(self)); -} - -/* - * call-seq: - * rand_shuffle!([seed = nil][,iter = 1]) - * - * fills the destination array with values from the look-up table. - * Indices of the entries are taken from the source array. That is, the function processes each element of src as following: - * dst(I)=lut[src(I)+DELTA] - * where DELTA=0 if src has depth :cv8u, and DELTA=128 if src has depth :cv8s. - */ -VALUE -rb_rand_shuffle_bang(int argc, VALUE *argv, VALUE self) -{ - VALUE seed, iter; - CvRNG rng; - rb_scan_args(argc, argv, "02", &seed, &iter); - if(NIL_P(seed)) - cvRandShuffle(CVARR(self), NULL, IF_INT(iter, 1)); - else{ - rng = cvRNG(rb_num2ll(seed)); - cvRandShuffle(CVARR(self), &rng, IF_INT(iter, 1)); - } - return self; -} - -/* - * call-seq: - * lut(lookup_table) -> cvmat - * - * Return new matrix performed lookup-table transforme. - * - * lookup_table should be CvMat that have 256 element (e.g. 1x256 matrix). - * Otherwise, raise CvStatusBadArgument error. - * - * And lookup_table should either have a single-channel, or the same number of channels. - * When single-channel lookup-table given, same table is used for all channels. - */ -VALUE -rb_lut(VALUE self, VALUE lut) -{ - VALUE dest = copy(self); - cvLUT(CVARR(self), CVARR(dest), CVARR(lut)); - return dest; -} - -/* - * call-seq: - * convert_scale(:depth => nil, :scale => 1.0, :shift => 0.0) - * - * Return new array with optional linear transformation. - * mat(I) = src(I) * scale + (shift, shift, ...) - */ -VALUE -rb_convert_scale(VALUE self, VALUE hash) -{ - if (TYPE(hash) != T_HASH) - rb_raise(rb_eTypeError, "argument should be Hash that contaion key [:depth, :scale, :shift]."); - VALUE depth = rb_hash_aref(hash, ID2SYM(rb_intern("depth"))), - scale = rb_hash_aref(hash, ID2SYM(rb_intern("scale"))), - shift = rb_hash_aref(hash, ID2SYM(rb_intern("shift"))), - dest = new_object(cvGetSize(CVARR(self)), CV_MAKETYPE(IF_DEPTH(depth, CV_MAT_DEPTH(CVMAT(self)->type)), CV_MAT_CN(CVMAT(self)->type))); - cvConvertScale(CVARR(self), CVARR(dest), IF_DBL(scale, 1.0), IF_DBL(shift, 0.0)); - return dest; -} - -/* - * call-seq: - * convert_scale_abs(:scale => 1.0, :shift => 0.0) - * - * Return new array with optional linear transformation. - * It is similar to CvMat#convert_scale, but it stores absolute values of the conversion result - * mat(I) = (src(I) * scale + (shift, shift, ...)).abs - */ -VALUE -rb_convert_scale_abs(VALUE self, VALUE hash) -{ - if (TYPE(hash) != T_HASH) - rb_raise(rb_eTypeError, "argument should be Hash that contaion key [:depth, :scale, :shift]."); - VALUE - scale = rb_hash_aref(hash, ID2SYM(rb_intern("scale"))), - shift = rb_hash_aref(hash, ID2SYM(rb_intern("shift"))), - dest = new_object(cvGetSize(CVARR(self)), CV_MAKETYPE(CV_8U, CV_MAT_CN(CVMAT(self)->type))); - cvConvertScale(CVARR(self), CVARR(dest), IF_DBL(scale, 1.0), IF_DBL(shift, 0.0)); - return dest; -} - -/* - * call-seq: - * add(val[,mask]) -> cvmat - * - * Return new matrix computed per-element sum. - * val should be CvMat or CvScalar. - * If val is CvMat, it must have same type (depth and channel). - * mask should be CvMat(8bit single-channel). - * For each element (I) - * dst(I) = src1(I) + src2(I) if mask(I) != 0 - */ -VALUE -rb_add(int argc, VALUE *argv, VALUE self) -{ - VALUE val, mask, dest; - rb_scan_args(argc, argv, "11", &val, &mask); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - if (rb_obj_is_kind_of(val, rb_klass)) - cvAdd(CVARR(self), CVARR(val), CVARR(dest), MASK(mask)); - else - cvAddS(CVARR(self), VALUE_TO_CVSCALAR(val), CVARR(dest), MASK(mask)); - return dest; -} - -/* - * call-seq: - * sub(val[,mask]) -> cvmat - * - * Return new matrix computed per-element difference. - * val should be CvMat or CvScalar. - * If val is CvMat, it must have same type (depth and channel). - * mask should be CvMat(8bit single-channel). - * For each element (I) - * dst(I) = src1(I) - src2(I) if mask(I) != 0 - */ -VALUE -rb_sub(int argc, VALUE *argv, VALUE self) -{ - VALUE val, mask, dest; - rb_scan_args(argc, argv, "11", &val, &mask); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - if (rb_obj_is_kind_of(val, rb_klass)) - cvSub(CVARR(self), CVARR(val), CVARR(dest), MASK(mask)); - else - cvSubS(CVARR(self), VALUE_TO_CVSCALAR(val), CVARR(dest), MASK(mask)); - return dest; -} - -/* - * call-seq: - * mul(val[,scale = 1.0]) -> cvmat - * - * Return new matrix computed per-element product. - * val should be CvMat or CvScalar. - * If val is CvMat, it must have same type (depth and channel). - * For each element (I) - * dst(I) = scale * src1(I) * src2(I) - */ -VALUE -rb_mul(int argc, VALUE *argv, VALUE self) -{ - VALUE val, scale, dest; - if (rb_scan_args(argc, argv, "11", &val, &scale) < 2) - scale = rb_float_new(1.0); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - if (rb_obj_is_kind_of(val, rb_klass)) { - cvMul(CVARR(self), CVARR(val), CVARR(dest), NUM2DBL(scale)); - }else{ - CvScalar scl = VALUE_TO_CVSCALAR(val); - VALUE mat = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvSet(CVARR(mat), scl); - cvMul(CVARR(self), CVARR(mat), CVARR(dest), NUM2DBL(scale)); - } - return dest; -} - -/* - * call-seq: - * div(val[,scale = 1.0]) -> cvmat - * - * Return new matrix computed per-element division. - * val should be CvMat or CvScalar. - * If val is CvMat, it must have same type (depth and channel). - * For each element (I) - * dst(I) = scale * src1(I) / src2(I) - */ -VALUE -rb_div(int argc, VALUE *argv, VALUE self) -{ - VALUE val, scale, dest; - if (rb_scan_args(argc, argv, "11", &val, &scale) < 2) - scale = rb_float_new(1.0); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - if (rb_obj_is_kind_of(val, rb_klass)) { - cvDiv(CVARR(self), CVARR(val), CVARR(dest), NUM2DBL(scale)); - }else{ - CvScalar scl = VALUE_TO_CVSCALAR(val); - VALUE mat = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvSet(CVARR(mat), scl); - cvDiv(CVARR(self), CVARR(mat), CVARR(dest), NUM2DBL(scale)); - } - return dest; -} - -/* - * call-seq: - * and(val[,mask]) -> cvmat - * - * Return new matrix computed per-element bit-wise conjunction. - * val should be CvMat or CvScalar. - * If val is CvMat, it must have same type (depth and channel). - * For each element (I) - * dst(I) = src1(I) & src2(I) if mask(I) != 0 - */ -VALUE -rb_and(int argc, VALUE *argv, VALUE self) -{ - VALUE val, mask, dest; - rb_scan_args(argc, argv, "11", &val, &mask); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - if (rb_obj_is_kind_of(val, rb_klass)) - cvAnd(CVARR(self), CVARR(val), CVARR(dest), MASK(mask)); - else - cvAndS(CVARR(self), VALUE_TO_CVSCALAR(val), CVARR(dest), MASK(mask)); - return dest; -} - -/* - * call-seq: - * or(val[,mask]) -> cvmat - * - * Return new matrix computed per-element bit-wise disjunction. - * val should be CvMat or CvScalar. - * If val is CvMat, it must have same type (depth and channel). - * For each element (I) - * dst(I) = src1(I) | src2(I) if mask(I) != 0 - */ -VALUE -rb_or(int argc, VALUE *argv, VALUE self) -{ - VALUE val, mask, dest; - rb_scan_args(argc, argv, "11", &val, &mask); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - if (rb_obj_is_kind_of(val, rb_klass)) - cvOr(CVARR(self), CVARR(val), CVARR(dest), MASK(mask)); - else - cvOrS(CVARR(self), VALUE_TO_CVSCALAR(val), CVARR(dest), MASK(mask)); - return dest; -} - -/* - * call-seq: - * xor(val[,mask]) -> cvmat - * - * Return new matrix computed per-element bit-wise "exclusive or" operation. - * val should be CvMat or CvScalar. - * If val is CvMat, it must have same type (depth and channel). - * For each element (I) - * dst(I) = src1(I) ^ src2(I) if mask(I) != 0 - */ -VALUE -rb_xor(int argc, VALUE *argv, VALUE self) -{ - VALUE val, mask, dest; - rb_scan_args(argc, argv, "11", &val, &mask); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - if (rb_obj_is_kind_of(val, rb_klass)) - cvXor(CVARR(self), CVARR(val), CVARR(dest), MASK(mask)); - else - cvXorS(CVARR(self), VALUE_TO_CVSCALAR(val), CVARR(dest), MASK(mask)); - return dest; -} - -/* - * call-seq: - * not -> cvmat - * - * Return new matrix performed per-element bit-wise inversion. - * dst(I) =~ src(I) - */ -VALUE -rb_not(VALUE self) -{ - VALUE dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvNot(CVARR(self), CVARR(dest)); - return dest; -} - -/* - * call-seq: - * not! -> self - * - * Performe per-element bit-wise inversion. - */ -VALUE -rb_not_bang(VALUE self) -{ - cvNot(CVARR(self), CVARR(self)); - return self; -} - -VALUE -rb_cmp_internal(VALUE self, VALUE val, int operand) -{ - VALUE dest = new_object(cvGetSize(CVARR(self)), CV_8U); - if (rb_obj_is_kind_of(val, rb_klass)) - cvCmp(CVARR(self), CVARR(val), CVARR(dest), operand); - else if (CV_MAT_CN(cvGetElemType(CVARR(self))) == 1 && rb_obj_is_kind_of(val, rb_cNumeric)) { - cvCmpS(CVARR(self), NUM2DBL(val), CVARR(dest), operand); - }else{ - VALUE mat = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvSet(CVARR(mat), VALUE_TO_CVSCALAR(val)); - cvCmp(CVARR(self), CVARR(mat), CVARR(dest), operand); - } - return dest; -} - -/* - * call-seq: - * eq(val) -> cvmat - * - * Return new matrix performed per-element comparision "equal". - * dst(I) = (self(I) == val(I) ? 0xFF : 0) - */ -VALUE -rb_eq(VALUE self, VALUE val) -{ - return rb_cmp_internal(self, val, CV_CMP_EQ); -} - -/* - * call-seq: - * gt(val) -> cvmat - * - * Return new matrix performed per-element comparision "greater than". - * dst(I) = (self(I) > val(I) ? 0xFF : 0) - */ -VALUE -rb_gt(VALUE self, VALUE val) -{ - return rb_cmp_internal(self, val, CV_CMP_GT); -} - -/* - * call-seq: - * ge(val) -> cvmat - * - * Return new matrix performed per-element comparision "greater or equal". - * dst(I) = (self(I) >= val(I) ? 0xFF : 0) - */ -VALUE -rb_ge(VALUE self, VALUE val) -{ - return rb_cmp_internal(self, val, CV_CMP_GE); -} - -/* - * call-seq: - * lt(val) -> cvmat - * - * Return new matrix performed per-element comparision "less than". - * dst(I) = (self(I) < val(I) ? 0xFF : 0) - */ -VALUE -rb_lt(VALUE self, VALUE val) -{ - return rb_cmp_internal(self, val, CV_CMP_LT); -} - -/* - * call-seq: - * le(val) -> cvmat - * - * Return new matrix performed per-element comparision "less or equal". - * dst(I) = (self(I) <= val(I) ? 0xFF : 0) - */ -VALUE -rb_le(VALUE self, VALUE val) -{ - return rb_cmp_internal(self, val, CV_CMP_LE); -} - -/* - * call-seq: - * ne(val) -> cvmat - * - * Return new matrix performed per-element comparision "not equal". - * dst(I) = (self(I) != val(I) ? 0xFF : 0) - */ -VALUE -rb_ne(VALUE self, VALUE val) -{ - return rb_cmp_internal(self, val, CV_CMP_NE); -} - -/* - * call-seq: - * in_range(min, max) -> cvmat - * - * Check that element lie between two object. - * min and max should be CvMat that have same size and type, or CvScalar. - * Return new matrix performed per-element, - * dst(I) = within the range ? 0xFF : 0 - */ -VALUE -rb_in_range(VALUE self, VALUE min, VALUE max) -{ - VALUE dest = dest = new_object(cvGetSize(CVARR(self)), CV_8UC1), tmp; - if (rb_obj_is_kind_of(min, rb_klass) && rb_obj_is_kind_of(max, rb_klass)) { - cvInRange(CVARR(self), CVARR(min), CVARR(max), CVARR(dest)); - }else if (rb_obj_is_kind_of(min, rb_klass)) { - tmp = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvSet(CVARR(tmp), VALUE_TO_CVSCALAR(max)); - cvInRange(CVARR(self), CVARR(min), CVARR(tmp), CVARR(dest)); - }else if (rb_obj_is_kind_of(max, rb_klass)) { - tmp = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvSet(CVARR(tmp), VALUE_TO_CVSCALAR(min)); - cvInRange(CVARR(self), CVARR(tmp), CVARR(max), CVARR(dest)); - }else - cvInRangeS(CVARR(self), VALUE_TO_CVSCALAR(min), VALUE_TO_CVSCALAR(max), CVARR(dest)); - return dest; -} - -/* - * call-seq: - * abs_diff(val) -> cvmat - * - * Calculate absolute difference between two. - * val should be CvMat that have same size and same type, or CvScalar. - * dst(I) = (src(I) - val(I)).abs - */ -VALUE -rb_abs_diff(VALUE self, VALUE val) -{ - VALUE dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - if (rb_obj_is_kind_of(val, rb_klass)) { - cvAbsDiff(CVARR(self), CVARR(val), CVARR(dest)); - }else{ - cvAbsDiffS(CVARR(self), CVARR(dest), VALUE_TO_CVSCALAR(val)); - } - return dest; -} - -/* - * call-seq: - * count_non_zero -> int - * - * Returns the number of non-zero elements. - * result = sumI arr(I)!=0 - * - * In case of IplImage both ROI and COI are supported. - */ -VALUE -rb_count_non_zero(VALUE self) -{ - return INT2FIX(cvCountNonZero(CVARR(self))); -} - -/* - * call-seq: - * sum -> scalar - * - * Return summerizes elements as CvScalar. Independently for each channel. - * - * note: If COI is setted in IplImage, the method processes the selected channel only and store the sum to the first component scalar[0]. - */ -VALUE -rb_sum(VALUE self) -{ - return cCvScalar::new_object(cvSum(CVARR(self))); -} - -/* - * call-seq: - * avg([mask]) -> mean(as scalar) - * - * Return the average(mean) of elements as CvScalar. Independently for each channel. - */ -VALUE -rb_avg(int argc, VALUE *argv, VALUE self) -{ - VALUE mask, mean; - rb_scan_args(argc, argv, "01", &mask); - - return cCvScalar::new_object(cvAvg(CVARR(self), MASK(mask))); -} - -/* - * call-seq: - * avg_sdv(mask) -> [mean(as scalar), std_dev(as scalar)] - * - * Calculates the average value and standard deviation of array elements, independently for each channel. - * - * note: same as [CvMat#avg, CvMat#sdv] - */ -VALUE -rb_avg_sdv(int argc, VALUE *argv, VALUE self) -{ - VALUE mask, mean, std_dev; - rb_scan_args(argc, argv, "01", &mask); - mean = cCvScalar::new_object(); - std_dev = cCvScalar::new_object(); - cvAvgSdv(CVARR(self), CVSCALAR(mean), CVSCALAR(std_dev), MASK(mask)); - return rb_ary_new3(2, mean, std_dev); -} - -/* - * call-seq: - * sdv([mask]) -> std_dev(as scalar) - * - * Return the standard deviation of elements as CvScalar. Independently for each channel. - */ -VALUE -rb_sdv(int argc, VALUE *argv, VALUE self) -{ - VALUE mask, std_dev; - rb_scan_args(argc, argv, "01", &mask); - std_dev = cCvScalar::new_object(); - cvAvgSdv(CVARR(self), NULL, CVSCALAR(std_dev), MASK(mask)); - return std_dev; -} - -/* - * call-seq: - * min_max_loc([mask]) -> [min_val, max_val, min_loc(as point), max_loc(as point)] - * - * Finds minimum and maximum element values and their positions. - * The extremums are searched over the whole array, selected ROI(in case of IplImage) or, if mask is not NULL, in the specified array region. - * If the array has more than one channel, it must be IplImage with COI set. - * In case if multi-dimensional arrays min_loc.x and max_loc.x will contain raw (linear) positions of the extremums. - */ -VALUE -rb_min_max_loc(int argc, VALUE *argv, VALUE self) -{ - VALUE mask, min_loc, max_loc; - double min_val = 0.0, max_val = 0.0; - rb_scan_args(argc, argv, "01", &mask); - min_loc = cCvPoint::new_object(); - max_loc = cCvPoint::new_object(); - cvMinMaxLoc(CVARR(self), &min_val, &max_val, CVPOINT(min_loc), CVPOINT(max_loc), MASK(mask)); - return rb_ary_new3(4, - rb_float_new(min_val), - rb_float_new(max_val), - min_loc, - max_loc); -} - -/* - * call-seq: - * dot_product(mat) -> float - * - * Calculates dot product of two arrays in Euclidian metrics. - * mat should be CvMat have same size and same type. - * - * src1.src2 = sum(src1(I) * src2(I)) - */ -VALUE -rb_dot_product(VALUE self, VALUE mat) -{ - if (!rb_obj_is_kind_of(mat, rb_klass)) - rb_raise(rb_eTypeError, "argument should be CvMat."); - return rb_float_new(cvDotProduct(CVARR(self), CVARR(mat))); -} - -/* - * call-seq: - * cross_product(mat) -> cvmat - * - * Calculate cross product of two 3D vectors. - * mat should be CvMat have same size and same type. - */ -VALUE -rb_cross_product(VALUE self, VALUE mat) -{ - if (!rb_obj_is_kind_of(mat, rb_klass)) - rb_raise(rb_eTypeError, "argument should be CvMat."); - VALUE dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvCrossProduct(CVARR(self), CVARR(mat), CVARR(dest)); - return dest; -} - -/* - * call-seq: - * transform(transmat[,shiftvec]) -> cvmat - * - * performs matrix transform of every element. - * dst(I) = transmat * src(I) + shiftvec - */ -VALUE -rb_transform(int argc, VALUE *argv, VALUE self) -{ - VALUE transmat, shiftvec; - rb_scan_args(argc, argv, "11", &transmat, &shiftvec); - VALUE dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvTransform(CVARR(self), CVARR(dest), CVMAT(transmat), MASK(shiftvec)); - return dest; -} - -/* - * call-seq: - * perspective_transform(mat) -> cvmat - * - * Return performed perspective matrix transform of vector array. - * mat should be 3x3 or 4x4 transform matrix (CvMat). - * Every element (by treating it as 2D or 3D vector) in the following way: - * (x, y, z) -> (x'/w, y'/w, z'/w) or - * (x, y) -> (x'/w, y'/w) - * where - * (x', y', z', w') = mat4x4*(x, y, z, 1) or - * (x', y', w') = mat3x3*(x, y, 1) - * and - * w = w' if w'!=0, inf otherwise. - */ -VALUE -rb_perspective_transform(VALUE self, VALUE mat) -{ - VALUE dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvPerspectiveTransform(CVARR(self), CVARR(dest), CVMAT(mat)); - return dest; -} - -/* - * call-seq: - * mul_transposed(:order => :default or :inverse, :delta => nil or cvmat) - * - * Calculates the product of self and its transposition. - * - * options - * * :order -> should be :default or :inverse (default is :default) - * see below. - * * :delta -> should be nil or CvMat (default is nil) - * An optional array, subtracted from source before multiplication. - * - * mul_transposed evaluates: - * :order => :default - * dst = (self - delta) * (self - delta)T - * :order => :inverse - * dst = (self - delta)T * (self - delta) - * - */ -VALUE -rb_mul_transposed(VALUE self, VALUE args) -{ - //VALUE options = extract_options_from_args_bang(args); - //assert_valid_keys(options, 2, "order", "delta"); - //VALUE order; - //OPTIONS(order, options, "order", ID2SYM(rb_intern("default"))); - //ID2SYM(rb_intern("order")), rb_intern("") - return Qnil; -} - - -/* - * call-seq: - * trace -> scalar - * - * Returns trace of matrix. "trace" is sum of diagonal elements of the matrix. - */ -VALUE -rb_trace(VALUE self) -{ - return cCvScalar::new_object(cvTrace(CVARR(self))); -} - -/* - * call-seq: - * transpose -> cvmat - * - * Return transposed matrix. - */ -VALUE -rb_transpose(VALUE self) -{ - CvSize size = cvGetSize(CVARR(self)); - VALUE dest = new_object(size.width, size.height, cvGetElemType(CVARR(self))); - cvTranspose(CVARR(self), CVARR(dest)); - return dest; -} - -/* - * call-seq: - * transpose! -> self - * - * Transposed matrix. - * - * rectangular matrix only (CvMat#square? = true). - */ -VALUE -rb_transpose_bang(VALUE self) -{ - cvTranspose(CVARR(self), CVARR(self)); - return self; -} - -/* - * call-seq: - * det -> float - * - * Return determinant of matrix. - * self should be single-channel and floating-point depth. - */ -VALUE -rb_det(VALUE self) -{ - return rb_float_new(cvDet(CVARR(self))); -} - -/* - * call-seq: - * invert(inversion_method=:lu[,delta]) -> float - * - * Finds inverse or pseudo-inverse of matrix. - * inversion_method should be following symbol. - * * :lu - * Gaussian elimincation with optimal pivot element chose. - * Return self determinant (self must be square). - * * :svd - * Singular value decomposition(SVD) method. - * Return the inversed condition number of self(ratio of the smallest singular value to the largest singular value) - * and 0 if self is all zeros. The SVD method calculate a pseudo-inverse matrix if self is singular. - * * :svd_sym or :svd_symmetric - * SVD method for a symmetric positively-defined matrix. - * - * self type should be single-channel and floating-point matrix. - */ -VALUE -rb_invert(int argc, VALUE *argv, VALUE self) -{ - VALUE symbol; - rb_scan_args(argc, argv, "01", &symbol); - int method = CVMETHOD("INVERSION_METHOD", symbol, CV_LU); - VALUE dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvInvert(CVARR(self), CVARR(dest), method); - return dest; -} - -/* - * call-seq: - * solve(mat, inversion_method=:lu) - * - * Solves linear system or least-squares problem (the latter is possible with SVD method). - * - * inversion_method should be following symbol. - * * :lu - * Gaussian elimincation with optimal pivot element chose. - * Return self determinant (self must be square). - * * :svd - * Singular value decomposition(SVD) method. - * Return the inversed condition number of self(ratio of the smallest singular value to the largest singular value) - * and 0 if self is all zeros. The SVD method calculate a pseudo-inverse matrix if self is singular. - * * :svd_sym or :svd_symmetric - * SVD method for a symmetric positively-defined matrix. - */ -VALUE -rb_solve(int argc, VALUE *argv, VALUE self) -{ - VALUE mat, symbol; - rb_scan_args(argc, argv, "11", &mat, &symbol); - if (!rb_obj_is_kind_of(mat, rb_klass)) - rb_raise(rb_eTypeError, "argument 1 (right-hand part of the linear system) should be %s.)", rb_class2name(rb_klass)); - VALUE dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvSolve(CVARR(self), CVARR(mat), CVARR(dest), CVMETHOD("INVERSION_METHOD", symbol, CV_LU)); - return dest; -} - -/* - * call-seq: - * svd(u = nil, v = nil) - * - * not implementated. - * Performs singular value decomposition of real floating-point matrix. - */ -VALUE -rb_svd(int argc, VALUE *argv, VALUE self) -{ - rb_raise(rb_eNotImpError, ""); - /* - VALUE u = Qnil, v = Qnil; - rb_scan_args(argc, argv, "02", &u, &v); - CvMat - *matU = NIL_P(u) ? NULL : CVARR(u), - *matV = NIL_P(v) ? NULL : CVARR(v); - cvSVD(CVARR(self), matU, matV); - return dest; - */ -} - -/* - * call-seq: - * svbksb - * - * not yet. - */ -VALUE -rb_svbksb(int argc, VALUE *argv, VALUE self) -{ - rb_raise(rb_eNotImpError, ""); -} - -/* - * call-seq: - * eigenvv([eps = 0.0]) -> [eigen_vectors(cvmat), eigen_values(cvmat)] - * - * Computes eigenvalues and eigenvectors of symmetric matrix. - * self should be symmetric square matrix. - * - * see #eigenvv! - */ -VALUE -rb_eigenvv(int argc, VALUE *argv, VALUE self) -{ - return rb_eigenvv_bang(argc, argv, copy(self)); -} - -/* - * call-seq: - * eigenvv!([eps = 0.0]) -> [eigen_vectors(cvmat), eigen_values(cvmat)] - * - * Computes eigenvalues and eigenvectors of symmetric matrix. - * self should be symmetric square matrix. self is modified during the processing. - * - * self * eigen_vectors(i,:)' = eigen_values(i) * eigen_vectors(i,:)' - * - * The contents of self is destroyed by this method. - * - * Currently the function is slower than #svd yet less accurate, so if self is known to be positively-defined - * (e.g., it is a convariation matrix), it is recommanded to use #svd to find eigenvalues and eigenvectors of self, - * especially if eigenvectors are not required. - */ -VALUE -rb_eigenvv_bang(int argc, VALUE *argv, VALUE self) -{ - VALUE epsilon; - double eps = rb_scan_args(argc, argv, "01", &epsilon) < 1 ? 0.0 : NUM2DBL(epsilon); - CvSize size = cvGetSize(CVARR(self)); - int type = cvGetElemType(CVARR(self)); - VALUE eigen_vectors = new_object(size, type), eigen_values = new_object(size.height, 1, type); - cvEigenVV(CVARR(self), CVARR(eigen_vectors), CVARR(eigen_values), eps); - return rb_ary_new3(2, eigen_vectors, eigen_values); -} - -/* - * call-seq: - * calc_covar_matrix() - * - * not yet. - * - */ -VALUE -rb_calc_covar_matrix(int argc, VALUE *argv, VALUE self) -{ - rb_raise(rb_eNotImpError, ""); -} - -/* - * call-seq: - * mahalonobis(vec, mat) -> float - * - * not yet. - */ -VALUE -rb_mahalonobis(int argc, VALUE *argv, VALUE self) -{ - rb_raise(rb_eNotImpError, ""); -} - - -/* - * call-seq: - * dft(anyflags...) -> cvmat - * - * Performs forward or inverse Discrete Fourier Transform(DFT) of 1D or 2D floating-point array. - * Argument should be following symbol or combination of these. - * - * * :forward or :inverse - * Do forward or inverse transform. The result is not scaled. - * * :scale - * Scale the result: divide it by the number of array elements. - * * :rows - * Do forward or inverse transform of every individual row of the self. - * This flag allow user to transofrm multiple vectors simulaneously and can be used to decrease the overhand - * (which sometimes several times larger then the processing itself), to do 3D and higher-dimensional transforms etc. - * - * e.g. - * mat.dft(:inverse) - * mat.dft(:forward, :scale) etc... - */ -VALUE -rb_dft(int argc, VALUE *argv, VALUE self) -{ - int type = CV_DXT_FORWARD; - if (argc > 0) { - for (int i = 0; i < argc; i++) { - type |= CVMETHOD("DXT_FLAG", argv[i]); - } - } - VALUE dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvDFT(CVARR(self), CVARR(dest), type); - return dest; -} - -/* - * call-seq: - * dct(anyflags...) -> cvmat - * - * Performs forward or inverse Discrete Cosine Transform(DCT) of 1D or 2D floating-point array. - * Argument should be following symbol or combination of these. - * - * * :forward or :inverse - * Do forward or inverse transform. - * * :rows - * Do forward or inverse transform of every individual row of the self. - * This flag allow user to transofrm multiple vectors simulaneously and can be used to decrease the overhand - * (which sometimes several times larger then the processing itself), to do 3D and higher-dimensional transforms etc. - */ -VALUE -rb_dct(int argc, VALUE *argv, VALUE self) -{ - int type = CV_DXT_FORWARD; - if (argc > 0) { - for (int i = 0; i < argc; i++) { - type |= CVMETHOD("DXT_FLAG", argv[i]); - } - } - VALUE dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvDCT(CVARR(self), CVARR(dest), type); - return dest; -} - -/* - * call-seq: - * line(p1, p2[, drawing_option]) -> mat - * - * Return image is drawn a line segment connecting two points. - * - * drawing_option should be Hash include these keys. - * :color - * Line color. - * :thickness - * Line Thickness. - * :line_type - * Type of the line: - * * 0 or 8 - 8-connected line(default). - * * 4 - 4-connected line. - * * negative-value - antialiased line. - * :shift - * Number of fractional bits in the point coordinates. - * - * note: drawing_option's default value is CvMat::DRAWING_OPTION. - * - * for example - * mat = CvMat.new(100, 100) - * mat.line(CvPoint.new(10, 10), CvPoint.new(90, 90), :thickness => 3, :line_type => :aa) - */ -VALUE -rb_line(int argc, VALUE *argv, VALUE self) -{ - return rb_line_bang(argc, argv, rb_clone(self)); -} - -/* - * call-seq: - * line!(p1, p2[, drawing_option]) -> self - * - * Draws a line segment connecting two points. - * Same as CvMat#line, but modifies the receiver in place. - * see CvMat#line - */ -VALUE -rb_line_bang(int argc, VALUE *argv, VALUE self) -{ - VALUE p1, p2, drawing_option; - rb_scan_args(argc, argv, "21", &p1, &p2, &drawing_option); - drawing_option = DRAWING_OPTION(drawing_option); - cvLine(CVARR(self), VALUE_TO_CVPOINT(p1), VALUE_TO_CVPOINT(p2), - DO_COLOR(drawing_option), - DO_THICKNESS(drawing_option), - DO_LINE_TYPE(drawing_option), - DO_SHIFT(drawing_option)); - return self; -} - -/* - * call-seq: - * rectangle(p1, p2[, drawing_option]) -> mat - * - * Return image is drawn a rectangle with two opposite corners p1 and p2. - * - * drawing_options should be Hash include these keys. - * :color - * Line color. - * :thickness - * Thickness of lines that make up the rectangle. - * Negative values make the function to draw a filled rectangle. - * :line_type - * Type of the line: - * * 0 or 8 - 8-connected line(default). - * * 4 - 4-connected line. - * * negative-value - antialiased line. - * :shift - * Number of fractional bits in the point coordinates. - * - * note: drawing_option's default value is CvMat::DRAWING_OPTION. - */ -VALUE -rb_rectangle(int argc, VALUE *argv, VALUE self) -{ - return rb_rectangle_bang(argc, argv, rb_clone(self)); -} - -/* - * call-seq: - * rectangle!(p1, p2[, drawing_option]) -> self - * - * Draws simple, thick or filled rectangle. - * Same as CvMat#rectangle, but modifies the receiver in place. - * see CvMat#rectangle - */ -VALUE -rb_rectangle_bang(int argc, VALUE *argv, VALUE self) -{ - VALUE p1, p2, drawing_option; - rb_scan_args(argc, argv, "21", &p1, &p2, &drawing_option); - drawing_option = DRAWING_OPTION(drawing_option); - cvRectangle(CVARR(self), VALUE_TO_CVPOINT(p1), VALUE_TO_CVPOINT(p2), - DO_COLOR(drawing_option), - DO_THICKNESS(drawing_option), - DO_LINE_TYPE(drawing_option), - DO_SHIFT(drawing_option)); - return self; -} - -/* - * call-seq: - * circle(center, radius[,drawing_option]) -> cvmat - * - * Return image is drawn a simple or filled circle with given center and radius. - * - * drawing_options should be Hash include these keys. - * :color - * Circle color. - * :thickness - * Thickness of the circle outline if positive, otherwise that a filled circle has to be drawn. - * :line_type - * Type of the circle boundary: - * * 0 or 8 - 8-connected line(default). - * * 4 - 4-connected line. - * * negative-value - antialiased line. - * :shift - * Number of fractional bits in the center coordinates and radius value. - * - * note: drawing_option's default value is CvMat::DRAWING_OPTION. - */ -VALUE -rb_circle(int argc, VALUE *argv, VALUE self) -{ - return rb_circle_bang(argc, argv, rb_clone(self)); -} - -/* - * call-seq: - * circle!(center, radius[,drawing_option]) -> cvmat - * - * Draw a circle. - * Same as CvMat#circle, but modifies the receiver in place. - * - * see CvMat#circle - */ -VALUE -rb_circle_bang(int argc, VALUE *argv, VALUE self) -{ - VALUE center, radius, drawing_option; - rb_scan_args(argc, argv, "21", ¢er, &radius, &drawing_option); - drawing_option = DRAWING_OPTION(drawing_option); - cvCircle(CVARR(self), VALUE_TO_CVPOINT(center), NUM2INT(radius), - DO_COLOR(drawing_option), - DO_THICKNESS(drawing_option), - DO_LINE_TYPE(drawing_option), - DO_SHIFT(drawing_option)); - return self; -} - -/* - * call-seq: - * ellipse(center, axis, angle, start_angle, end_angle[,drawing_option]) -> mat - * - * Return image is drawn a simple or thick elliptic arc or fills an ellipse sector. - * - * drawing_options should be Hash include these keys. - * :color - * Ellipse color. - * :thickness - * Thickness of the ellipse arc. - * :line_type - * Type of the ellipse boundary: - * * 0 or 8 - 8-connected line(default). - * * 4 - 4-connected line. - * * negative-value - antialiased line. - * :shift - * Number of fractional bits in the center coordinates and axes' value. - * - * note: drawing_option's default value is CvMat::DRAWING_OPTION. - */ -VALUE -rb_ellipse(int argc, VALUE *argv, VALUE self) -{ - return rb_ellipse_bang(argc, argv, rb_clone(self)); -} - -/* - * call-seq: - * ellipse!(center, axis, angle, start_angle, end_angle[,drawing_option]) -> self - * - * Draws simple or thick elliptic arc or fills ellipse sector. - * Same as CvMat#ellipse, but modifies the receiver in place. - * - * see CvMat#ellipse - */ -VALUE -rb_ellipse_bang(int argc, VALUE *argv, VALUE self) -{ - VALUE center, axis, angle, start_angle, end_angle, drawing_option; - rb_scan_args(argc, argv, "51", ¢er, &axis, &angle, &start_angle, &end_angle, &drawing_option); - drawing_option = DRAWING_OPTION(drawing_option); - cvEllipse(CVARR(self), VALUE_TO_CVPOINT(center), - VALUE_TO_CVSIZE(axis), - NUM2DBL(angle), NUM2DBL(start_angle), NUM2DBL(end_angle), - DO_COLOR(drawing_option), - DO_THICKNESS(drawing_option), - DO_LINE_TYPE(drawing_option), - DO_SHIFT(drawing_option)); - return self; -} - -/* - * call-seq: - * ellipse_box(box[, drawing_option]) -> mat - * - * Return image is drawn a simple or thick ellipse outline, or fills an ellipse. - * The method provides a convenient way to draw an ellipse approximating some shape. - * - * drawing_options should be Hash include these keys. - * :color - * Ellipse color. - * :thickness - * Thickness of the ellipse drawn. - * :line_type - * Type of the ellipse boundary: - * * 0 or 8 - 8-connected line(default). - * * 4 - 4-connected line. - * * negative-value - antialiased line. - * :shift - * Number of fractional bits in the box vertex coordinates. - * - * note: drawing_option's default value is CvMat::DRAWING_OPTION. - */ -VALUE -rb_ellipse_box(int argc, VALUE *argv, VALUE self) -{ - return rb_ellipse_box_bang(argc, argv, rb_clone(self)); -} - -/* - * call-seq: - * ellipse_box!(box[, drawing_option]) -> self - * - * Draws simple or thick elliptic arc or fills ellipse sector. - * Same as CvMat#ellipse_box, but modifies the receiver in place. - * - * see CvMat#ellipse_box - */ -VALUE -rb_ellipse_box_bang(int argc, VALUE *argv, VALUE self) -{ - VALUE box, drawing_option; - rb_scan_args(argc, argv, "11", &box, &drawing_option); - drawing_option = DRAWING_OPTION(drawing_option); - cvEllipseBox(CVARR(self), VALUE_TO_CVBOX2D(box), - DO_COLOR(drawing_option), - DO_THICKNESS(drawing_option), - DO_LINE_TYPE(drawing_option), - DO_SHIFT(drawing_option)); - return self; -} - -/* - * call-seq: - * fill_poly(points[,drawing_option]) -> mat - * - * Return image is filled an area bounded by several polygonal contours. - * The method fills complex areas, for example, areas with holes, contour self-intersection, etc. - */ -VALUE -rb_fill_poly(int argc, VALUE *argv, VALUE self) -{ - return rb_fill_poly_bang(argc, argv, self); -} - -/* - * call-seq: - * fill_poly!(points[,drawing_option]) -> self - * - * Fills polygons interior. - * Same as CvMat#fill_poly, but modifies the receiver in place. - * - * drawing_options should be Hash include these keys. - * :color - * Polygon color. - * :line_type - * Type of the polygon boundaries: - * * 0 or 8 - 8-connected line(default). - * * 4 - 4-connected line. - * * negative-value - antialiased line. - * :shift - * Number of fractional bits in the vertex coordinates. - * - * note: drawing_option's default value is CvMat::DRAWING_OPTION. - */ -VALUE -rb_fill_poly_bang(int argc, VALUE *argv, VALUE self) -{ - VALUE points, drawing_option; - rb_scan_args(argc, argv, "11", &points, &drawing_option); - drawing_option = DRAWING_OPTION(drawing_option); - if (!POINT_SET_P(points)) - rb_raise(rb_eTypeError, "argument 1(points) should be %s.", cCvSeq::rb_class()); - /* // todo : draw multi-sequence polygon - CvSeq *seq = CVSEQ(points); - int contours = 1; - while(seq = seq->h_next) - contours++; - int **nps = ALLOCA_N(int*, contours); - CvPoint **ps = ALLOCA_N(CvPoint*, contours); - seq = CVSEQ(points); - for (int i = 0; i < contours; i++) { - } - */ - int np = CVSEQ(points)->total; - VALUE tmp = cCvMat::new_object(1, np, CV_32SC2); - CvPoint *p = (CvPoint*)cvCvtSeqToArray(CVSEQ(points), CVMAT(tmp)->data.ptr, CV_WHOLE_SEQ); - cvFillPoly(CVARR(self), - &p, - &np, - 1, //contours - DO_COLOR(drawing_option), - DO_LINE_TYPE(drawing_option), - DO_SHIFT(drawing_option)); - return self; -} - -/* - * call-seq: - * fill_convex_poly(points[,drawing_option]) -> mat - * - * Return image is filled convex polygon interior. - * This method is much faster than The function CvMat#fill_poly - * and can fill not only the convex polygons but any monotonic polygon, - * i.e. a polygon whose contour intersects every horizontal line (scan line) - * twice at the most. - * - * drawing_options should be Hash include these keys. - * :color - * Polygon color. - * :line_type - * Type of the polygon boundaries: - * * 0 or 8 - 8-connected line(default). - * * 4 - 4-connected line. - * * negative-value - antialiased line. - * :shift - * Number of fractional bits in the vertex coordinates. - * - * note: drawing_option's default value is CvMat::DRAWING_OPTION. - */ -VALUE -rb_fill_convex_poly(int argc, VALUE *argv, VALUE self) -{ - return rb_fill_convex_poly_bang(argc, argv, rb_clone(self)); -} - -/* - * call-seq: - * fill_convex_poly!(points[,drawing_option]) -> self - * - * Fills convex polygon. - * Same as CvMat#fill_convex_poly, but modifies the receiver in place. - * - * see CvMat#fill_cnovex_poly - */ -VALUE -rb_fill_convex_poly_bang(int argc, VALUE *argv, VALUE self) -{ - VALUE points, drawing_option; - rb_scan_args(argc, argv, "11", &points, &drawing_option); - drawing_option = DRAWING_OPTION(drawing_option); - if (!POINT_SET_P(points)) - rb_raise(rb_eTypeError, "argument 1(points) should be %s.", cCvSeq::rb_class()); - int np = CVSEQ(points)->total; - VALUE tmp = cCvMat::new_object(1, np, CV_32SC2); - CvPoint *p = (CvPoint*)cvCvtSeqToArray(CVSEQ(points), CVMAT(tmp)->data.ptr, CV_WHOLE_SEQ); - cvFillConvexPoly(CVARR(self), - p, - np, - DO_COLOR(drawing_option), - DO_LINE_TYPE(drawing_option), - DO_SHIFT(drawing_option)); - return self; -} - -/* - * call-seq: - * poly_line(points[,drawing_option]) -> mat - * - * Return image drawed a single or multiple polygonal curves. - * - * drawing_option should be Hash include these keys. - * :is_closed - * Indicates whether the polylines must be drawn closed. - * If closed, the method draws the line from the last vertex - * of every contour to the first vertex. - * :color - * Polyline color. - * :thickness - * Thickness of the polyline edges - * :line_type - * Type of line segments: - * * 0 or 8 - 8-connected line(default). - * * 4 - 4-connected line. - * * negative-value - antialiased line. - * :shift - * Number of fractional bits in the vertex coordinates. - * - * note: drawing_option's default value is CvMat::DRAWING_OPTION. - */ -VALUE -rb_poly_line(int argc, VALUE *argv, VALUE self) -{ - return rb_poly_line_bang(argc, argv, rb_clone(self)); -} - -/* - * call-seq: - * poly_line!(points[,drawing_option]) -> self - * - * Draws simple or thick polygons. - * - * Same as CvMat#poly_line, but modifies the receiver in place. - * - * see CvMat#poly_line - */ -VALUE -rb_poly_line_bang(int argc, VALUE *argv, VALUE self) -{ - VALUE points, drawing_option; - rb_scan_args(argc, argv, "11", &points, &drawing_option); - drawing_option = DRAWING_OPTION(drawing_option); - /* - if (!POINT_SET_P(points)) - rb_raise(rb_eTypeError, "argument 1(points) should be %s.", cCvSeq::rb_class()); - int np = CVSEQ(points)->total; - VALUE tmp = cCvMat::new_object(1, np, CV_32SC2); - CvPoint *p = (CvPoint*)cvCvtSeqToArray(CVSEQ(points), CVMAT(tmp)->data.ptr, CV_WHOLE_SEQ); - // todo: multi-sequence polygon - cvPolyLine(CVARR(self), - &p, - &np, - 1, //contour - DO_IS_CLOSED(drawing_option), - DO_COLOR(drawing_option), - DO_THICKNESS(drawing_option), - DO_LINE_TYPE(drawing_option), - DO_SHIFT(drawing_option)); - */ - CvPoint *pointset = 0; - int length = CVPOINTS_FROM_POINT_SET(points, &pointset); - cvPolyLine(CVARR(self), - &pointset, - &length, - 1, //contour - DO_IS_CLOSED(drawing_option), - DO_COLOR(drawing_option), - DO_THICKNESS(drawing_option), - DO_LINE_TYPE(drawing_option), - DO_SHIFT(drawing_option)); - - return self; -} - -/* - * call-seq: - * put_text(str, point, font[,color]) -> cvmat - * - * Return image is drawn text string. - * font should be CvFont object. - */ -VALUE -rb_put_text(int argc, VALUE *argv, VALUE self) -{ - return rb_put_text_bang(argc, argv, rb_clone(self)); -} - -/* - * call-seq: - * put_text!(str, point ,font[,color]) -> self - * - * Draws text string. Return self. - */ -VALUE -rb_put_text_bang(int argc, VALUE *argv, VALUE self) -{ - VALUE text, point, font, color; - rb_scan_args(argc, argv, "22", &text, &point, &font, &color); - cvPutText(CVARR(self), StringValueCStr(text), VALUE_TO_CVPOINT(point), CVFONT(font), *CVSCALAR(color)); - return self; -} - -/* - * call-seq: - * sobel(xorder,yorder[,aperture_size=3]) -> cvmat - * - * Calculates first, second, third or mixed image derivatives using extended Sobel operator. - * self should be single-channel 8bit signed/unsigned or 32bit floating-point. - * - * link:../images/CvMat_sobel.png - */ -VALUE -rb_sobel(int argc, VALUE *argv, VALUE self) -{ - VALUE xorder, yorder, aperture_size, dest; - if (rb_scan_args(argc, argv, "21", &xorder, &yorder, &aperture_size) < 3) - aperture_size = INT2FIX(3); - switch(CV_MAT_DEPTH(CVMAT(self)->type)) { - case CV_8U: - case CV_8S: - dest = new_object(cvGetSize(CVARR(self)), CV_MAKETYPE(CV_16S, 1)); - break; - case CV_32F: - dest = new_object(cvGetSize(CVARR(self)), CV_MAKETYPE(CV_32F, 1)); - break; - default: - rb_raise(rb_eNotImpError, "source depth should be CV_8U or CV_8S or CV_32F."); - } - cvSobel(CVARR(self), CVARR(dest), NUM2INT(xorder), NUM2INT(yorder), NUM2INT(aperture_size)); - return dest; -} - -/* - * call-seq: - * laplace([aperture_size = 3]) -> cvmat - * - * Calculates Laplacian of the image. - * self should be single-channel 8bit signed/unsigned or 32bit floating-point. - */ -VALUE -rb_laplace(int argc, VALUE *argv, VALUE self) -{ - VALUE aperture_size, dest; - if (rb_scan_args(argc, argv, "01", &aperture_size) < 1) - aperture_size = INT2FIX(3); - switch(CV_MAT_DEPTH(CVMAT(self)->type)) { - case CV_8U: - case CV_8S: - dest = new_object(cvGetSize(CVARR(self)), CV_MAKETYPE(CV_16S, 1)); - break; - case CV_32F: - dest = new_object(cvGetSize(CVARR(self)), CV_MAKETYPE(CV_32F, 1)); - break; - default: - rb_raise(rb_eNotImpError, "source depth should be CV_8U or CV_8S or CV_32F."); - } - cvLaplace(CVARR(self), CVARR(dest), NUM2INT(aperture_size)); - return dest; -} - -/* - * call-seq: - * canny(thresh1,thresh2[,aperture_size = 3]) -> cvmat - * - * Canny algorithm for edge detection. - */ -VALUE -rb_canny(int argc, VALUE *argv, VALUE self) -{ - VALUE thresh1, thresh2, aperture_size; - if (rb_scan_args(argc, argv, "21", &thresh1, &thresh2, &aperture_size) < 3) - aperture_size = INT2FIX(3); - VALUE dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvCanny(CVARR(self), CVARR(dest), NUM2INT(thresh1), NUM2INT(thresh2), NUM2INT(aperture_size)); - return dest; -} - -/* - * call-seq: - * pre_corner_detect([aperture_size = 3]) -> cvmat - * - * Calculates feature map for corner detection. - * aperture_size is parameter for sobel operator(see #sobel). - * - * The corners can be found as local maximums of the function. - */ -VALUE -rb_pre_corner_detect(int argc, VALUE *argv, VALUE self) -{ - VALUE aperture_size, dest; - if (rb_scan_args(argc, argv, "01", &aperture_size) < 1) - aperture_size = INT2FIX(3); - dest = new_object(cvGetSize(CVARR(self)), CV_MAKETYPE(CV_32F, 1)); - cvPreCornerDetect(CVARR(self), CVARR(dest), NUM2INT(aperture_size)); - return dest; -} - -/* - * call-seq: - * corner_eigenvv(block_size[,aperture_size]) -> cvmat - * - * For every pixel considers block_size x block_size neighborhood S(p). - * It calculates convariation matrix of derivatives over the neighborhood. - */ -VALUE -rb_corner_eigenvv(int argc, VALUE *argv, VALUE self) -{ - VALUE block_size, aperture_size, dest; - if (rb_scan_args(argc, argv, "11", &block_size, &aperture_size) < 1) - aperture_size = INT2FIX(3); - Check_Type(block_size, T_FIXNUM); - CvSize size = cvGetSize(CVARR(self)); - dest = new_object(cvSize(size.width * 6, size.height), CV_MAKETYPE(CV_32F, 1)); - cvCornerEigenValsAndVecs(CVARR(self), CVARR(dest), NUM2INT(block_size), NUM2INT(aperture_size)); - return dest; -} - -/* - * call-seq: - * corner_min_eigen_val(block_size[,aperture_size = 3]) -> cvmat - * - * Calculates minimal eigenvalue of gradient matrices for corner detection. - */ -VALUE -rb_corner_min_eigen_val(int argc, VALUE *argv, VALUE self) -{ - VALUE block_size, aperture_size, dest; - rb_scan_args(argc, argv, "11", &block_size, &aperture_size); - dest = new_object(cvGetSize(CVARR(self)), CV_MAKETYPE(CV_32F, 1)); - cvCornerMinEigenVal(CVARR(self), CVARR(dest), FIX2INT(block_size), FIX2INT(aperture_size)); - return dest; -} - -/* - * call-seq: - * corner_harris(block_size[,aperture_size = 3][,k = 0.04]) -> cvmat - * - * Return image Applied Harris edge detector. - */ -VALUE -rb_corner_harris(int argc, VALUE *argv, VALUE self) -{ - SUPPORT_8UC1_ONLY(self); - VALUE block_size, aperture_size, k, dest; - rb_scan_args(argc, argv, "12", &block_size, &aperture_size, &k); - dest = new_object(cvGetSize(CVARR(self)), CV_MAKETYPE(CV_32F, 1)); - cvCornerHarris(CVARR(self), CVARR(dest), FIX2INT(block_size), IF_INT(aperture_size, 3), IF_DBL(k, 0.04)); - return dest; -} - -/* - * call-seq: - * find_corner_sub_pix() - * - * Refines corner locations. - * This method iterates to find the sub-pixel accurate location of corners, - * or radial saddle points, as shown in on the picture below. - */ -VALUE -rbi_find_corner_sub_pix(int argc, VALUE *argv, VALUE self) -{ - /* - VALUE corners, win, zero_zone, criteria; - rb_scan_args(argc, argv, "13", &corners, &win, &zero_zone, &criteria); - if (!rb_obj_is_kind_of(corners, mPointSet::rb_module())) - rb_raise(rb_eTypeError, "argument 1 (corners) should be %s.", rb_class2name(mPointSet::rb_module())); - int count = CVSEQ(corners)->total; - VALUE storage = cCvMemStorage::new_object(); - CvPoint2D32f *pointset = POINTSET2D32f(corners); - //cvFindCornerSubPix(CVARR(self), pointset, count, VALUE_TO_CVSIZE(win), VALUE_TO_CVSIZE(zero_zone), VALUE_TO_CVTERMCRITERIA(criteria)); - //return cCvSeq::new_sequence(); - */ - return Qnil; -} - -VALUE -rb_good_features_to_track(int argc, VALUE *argv, VALUE self) -{ - VALUE quality_level, min_distance, good_features_to_track_option, eigen, tmp, storage; - rb_scan_args(argc, argv, "21", &quality_level, &min_distance, &good_features_to_track_option); - good_features_to_track_option = GOOD_FEATURES_TO_TRACK_OPTION(good_features_to_track_option); - CvMat *src = CVMAT(self); - eigen = cCvMat::new_object(cvGetSize(src), CV_MAKETYPE(CV_32F, 1)); - tmp = cCvMat::new_object(cvGetSize(src), CV_MAKETYPE(CV_32F, 1)); - int np = GF_MAX(good_features_to_track_option); - if(!(np > 0)) - rb_raise(rb_eArgError, "option :max should be positive value."); - CvPoint2D32f *p32 = (CvPoint2D32f*)cvAlloc(sizeof(CvPoint2D32f) * np); - if(!p32) - rb_raise(rb_eNoMemError, "failed allocate memory."); - cvGoodFeaturesToTrack(src, CVARR(eigen), CVARR(tmp), p32, &np, NUM2DBL(quality_level), NUM2DBL(min_distance), - GF_MASK(good_features_to_track_option), - GF_BLOCK_SIZE(good_features_to_track_option), - GF_USE_HARRIS(good_features_to_track_option), - GF_K(good_features_to_track_option)); - storage = cCvMemStorage::new_object(); - CvSeq *pseq = cvCreateSeq(CV_SEQ_POINT_SET, sizeof(CvSeq), sizeof(CvPoint2D32f), CVMEMSTORAGE(storage)); - cvSeqPushMulti(pseq, p32, np); - cvFree(&p32); - return cCvSeq::new_sequence(cCvSeq::rb_class(), pseq, cCvPoint2D32f::rb_class(), storage); -} - -/* - * call-seq: - * sample_line(p1, p2[,connectivity = 8]) {|pixel| } - * - * not yet. - */ -VALUE -rb_sample_line(int argc, VALUE *argv, VALUE self) -{ - /* - VALUE p1, p2, connectivity; - if (rb_scan_args(argc, argv, "21", &p1, &p2, &connectivity) < 3) - connectivity = INT2FIX(8); - CvPoint point1 = VALUE_TO_CVPOINT(p1), point2 = VALUE_TO_CVPOINT(p2); - int size; - switch(FIX2INT(connectivity)) { - case 4: - size = abs(point2.x - point1.x) + abs(point2.y - point1.y) + 1; - break; - case 8: - size = maxint(abs(point2.x - point1.x) + 1, abs(point2.y - point1.y) + 1); - break; - default: - rb_raise(rb_eArgError, "argument 3(connectivity) should be 4 or 8. 8 is default."); - } - VALUE buf = cCvMat::new_object(1, size, cvGetElemType(CVARR(self))); - cvSampleLine(CVARR(self), point1, point2, CVMAT(buf)->data.ptr, FIX2INT(connectivity)); - if (rb_block_given_p()) { - for(int i = 0; i < size; i++) { - //Data_Wrap_Struct(cCvScalar::rb_class(), 0, 0, CVMAT(buf)->data.ptr[]); - //rb_yield(cCvScalar::new_object); - } - } - return buf; - */ - return Qnil; -} - -/* - * call-seq: - * rect_sub_pix(center,size) -> cvmat - * - * Retrieves pixel rectangle from image with sub-pixel accuracy. - * Extracts pixels from self. - * dst(x,y) = self(x + center.x - (size.width - 1) * 0.5, y + center.y - (size.height - 1) * 0.5) - * where the values of pixels at non-integer coordinates are retrived using bilinear iterpolation. - * Every channel of multiple-channel images is processed independently. - * Whereas the rectangle center must be inside the image, the whole rectangle may be partially occludedl. - * In this case, the replication border mode is used to get pixel values beyond the image boundaries. - */ -VALUE -rb_rect_sub_pix(VALUE self, VALUE center, VALUE size) -{ - VALUE dest = new_object(VALUE_TO_CVSIZE(size), cvGetElemType(CVARR(self))); - cvGetRectSubPix(CVARR(self), CVARR(dest), VALUE_TO_CVPOINT2D32F(center)); - return dest; -} - -/* - * call-seq: - * quandrangle_sub_pix(map_matrix) -> cvmat - * - * Retrives pixel quadrangle from image with sub-pixel accuracy. - * Extracts pixel from self at sub-pixel accuracy and store them: - */ -VALUE -rb_quadrangle_sub_pix(VALUE self, VALUE map_matrix, VALUE size) -{ - if (!rb_obj_is_kind_of(map_matrix, cCvMat::rb_class())) - rb_raise(rb_eTypeError, "argument 1 (map matrix) should be %s (2x3).", rb_class2name(cCvMat::rb_class())); - VALUE dest = new_object(VALUE_TO_CVSIZE(size), cvGetElemType(CVARR(self))); - cvGetQuadrangleSubPix(CVARR(self), CVARR(dest), CVMAT(map_matrix)); - return dest; -} - -/* - * call-seq: - * resize(size[,interpolation = :linear]) -> cvmat - * - * Resize image. - * interpolation is interpolation method: - * * :nn - * nearest-neighbor interpolation. - * * :linear - * bilinear interpolation (used by default) - * * :area - * resampling using pixel area relation. It is preferred method for image decimation that give moire-free results. - * In case of zooming it is similar to NN method. - * * :cubic - * bicubic interpolation. - * Return self resized image that it fits exactly to size. If ROI is set, the method consideres the ROI as supported as usual. - */ -VALUE -rb_resize(int argc, VALUE *argv, VALUE self) -{ - VALUE size, interpolation; - rb_scan_args(argc, argv, "11", &size, &interpolation); - VALUE dest = new_object(VALUE_TO_CVSIZE(size), cvGetElemType(CVARR(self))); - cvResize(CVARR(self), CVARR(dest), CVMETHOD("INTERPOLATION_METHOD", interpolation, CV_INTER_LINEAR)); - return self; -} - -/* - * call-seq: - * warp_affine(map_matrix[,interpolation = :linear][,option = :fill_outliers][,fillval = 0]) -> cvmat - * - * Applies affine transformation to the image. - */ -VALUE -rb_warp_affine(int argc, VALUE *argv, VALUE self) -{ - VALUE map_matrix, interpolation, option, fill_value; - if (rb_scan_args(argc, argv, "13", &map_matrix, &interpolation, &option, &fill_value) < 4) - fill_value = INT2FIX(0); - if (!rb_obj_is_kind_of(map_matrix, cCvMat::rb_class())) - rb_raise(rb_eTypeError, "argument 1 (map matrix) should be %s (2x3).", rb_class2name(cCvMat::rb_class())); - VALUE dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvWarpAffine(CVARR(self), CVARR(dest), CVMAT(map_matrix), - CVMETHOD("INTERPOLATION_METHOD", interpolation, CV_INTER_LINEAR) | CVMETHOD("WARP_FLAG", option, CV_WARP_FILL_OUTLIERS), VALUE_TO_CVSCALAR(fill_value)); - return dest; -} - -/* - * call-seq: - * CvMat.rotation(center,angle,scale) -> cvmat - * - * Create new affine matrix of 2D rotation (2x3 32bit floating-point matrix). - * center is center of rotation (x, y). - * angle is rotation angle in degrees. - * Positive values mean counter-clockwise rotation - * (the coordinate origin is assumed at top-left corner). - * scale is isotropic scale factor. - * - * [ a b | (1 - a) * center.x - b * center.y ] - * [-b a | (b * center.x + (1 + a) * center.y ] - * where a = scale * cos(angle), b = scale * sin(angle) - */ -VALUE -rb_rotation(VALUE self, VALUE center, VALUE angle, VALUE scale) -{ - VALUE map_matrix = new_object(cvSize(3,2), CV_MAKETYPE(CV_32F, 1)); - cv2DRotationMatrix(VALUE_TO_CVPOINT2D32F(center), NUM2DBL(angle), NUM2DBL(scale), CVMAT(map_matrix)); - return map_matrix; -} - -/* - * call-seq: - * warp_perspective(map_matrix[,interpolation=:linear][,option =:fill_outliers][,fillval=0])) -> cvmat - * - * Applies perspective transformation to the image. - */ -VALUE -rb_warp_perspective(int argc, VALUE *argv, VALUE self) -{ - VALUE map_matrix, interpolation, option, fillval; - if (rb_scan_args(argc, argv, "13", &map_matrix, &interpolation, &option, &fillval) < 4) - fillval = INT2FIX(0); - if (!rb_obj_is_kind_of(map_matrix, cCvMat::rb_class())) - rb_raise(rb_eTypeError, "argument 1 (map matrix) should be %s (3x3).", rb_class2name(cCvMat::rb_class())); - VALUE dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvWarpPerspective(CVARR(self), CVARR(dest), CVMAT(map_matrix), - CVMETHOD("INTERPOLATION_METHOD", interpolation, CV_INTER_LINEAR) | CVMETHOD("WARP_FLAG", option, CV_WARP_FILL_OUTLIERS), VALUE_TO_CVSCALAR(fillval)); - return dest; -} - -/* - * call-seq: - * remap(mapx,mapy[,interpolation=:linear][,option=:fill_outliers][,fillval=0]) -> cvmat - * - * Applies generic geometrical transformation to the image. - * Transforms source image using the specified map: - * dst(x,y)<-src(mapx(x,y),mapy(x,y)) - * Similar to other geometrical transformations, some interpolation method (specified by user) is used to - * extract pixels with non-integer coordinates. - */ -VALUE -rb_remap(int argc, VALUE *argv, VALUE self) -{ - VALUE mapx, mapy, interpolation, option, fillval; - if (rb_scan_args(argc, argv, "23", &mapx, &mapy, &interpolation, &option, &fillval) < 5) - fillval = INT2FIX(0); - if (!rb_obj_is_kind_of(mapx, cCvMat::rb_class())) - rb_raise(rb_eTypeError, "argument 1 (map of x-coordinates) should be %s(CV_32F and single-channel).", rb_class2name(cCvMat::rb_class())); - if (!rb_obj_is_kind_of(mapy, cCvMat::rb_class())) - rb_raise(rb_eTypeError, "argument 2 (map of y-coordinates) should be %s(CV_32F and single-channel).", rb_class2name(cCvMat::rb_class())); - VALUE dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvRemap(CVARR(self), CVARR(dest), CVARR(mapx), CVARR(mapy), - CVMETHOD("INTERPOLATION_METHOD", interpolation, CV_INTER_LINEAR) | CVMETHOD("WARP_FLAG", option, CV_WARP_FILL_OUTLIERS), VALUE_TO_CVSCALAR(fillval)); - return dest; -} - -/* - * call-seq: - * log_polar(center, magnitude, ) - * - * Remaps image to log-polar space. - */ -VALUE -rb_log_polar(int argc, VALUE *argv, VALUE self) -{ - /* - VALUE size, center, m, flags, fillval, dest; - rb_scan_args(argc, argv, "3*", &size, ¢er, &m, &flags); - dest = cCvMat::new_object(); - cvLogPolar(CVARR(self), CVARR(dest), - VALUE_TO_CVPOINT2D32F(center), NUM2DBL(m), - CVMETHOD("INTERPOLATION_METHOD", interpolation, CV_INTER_LINEAR) | CVMETHOD("WARP_FLAG", option, CV_WARP_FILL_OUTLIEARS), VALUE_TO_CVSCALAR(fillval)); - return dest; - */ - return Qnil; -} - -/* - * call-seq: - * erode([element = nil, iteration = 1]) -> cvmat - * - * Create erodes image by using arbitrary structuring element. - * element is structuring element used for erosion. - * element should be IplConvKernel. If it is nil, a 3x3 rectangular structuring element is used. - * iterations is number of times erosion is applied. - */ -VALUE -rb_erode(int argc, VALUE *argv, VALUE self) -{ - return rb_erode_bang(argc, argv, rb_clone(self)); -} - -/* - * call-seq: - * erode!([element = nil][,iteration = 1]) -> self - * - * Erodes image by using arbitrary structuring element. - * see also #erode. - */ -VALUE -rb_erode_bang(int argc, VALUE *argv, VALUE self) -{ - VALUE element, iteration; - rb_scan_args(argc, argv, "02", &element, &iteration); - cvErode(CVARR(self), CVARR(self), IPLCONVKERNEL(element), IF_INT(iteration, 1)); - return self; -} - -/* - * call-seq: - * dilate([element = nil][,iteration = 1]) -> cvmat - * - * Create dilates image by using arbitrary structuring element. - * element is structuring element used for erosion. - * element should be IplConvKernel. If it is nil, a 3x3 rectangular structuring element is used. - * iterations is number of times erosion is applied. - */ -VALUE -rb_dilate(int argc, VALUE *argv, VALUE self) -{ - return rb_dilate_bang(argc, argv, rb_clone(self)); -} - -/* - * call-seq: - * dilate!([element = nil][,iteration = 1]) -> self - * - * Dilate image by using arbitrary structuring element. - * see also #dilate. - */ -VALUE -rb_dilate_bang(int argc, VALUE *argv, VALUE self) -{ - VALUE element, iteration; - rb_scan_args(argc, argv, "02", &element, &iteration); - cvDilate(CVARR(self), CVARR(self), IPLCONVKERNEL(element), IF_INT(iteration, 1)); - return self; -} - -/* - * call-seq: - * morpholohy_open([element = nil][,iteration = 1]) -> cvmat - * - * Performs advanced morphological transformations "Opening". - * dilate(erode(src,element),element) - */ -VALUE -rb_morphology_open(int argc, VALUE *argv, VALUE self) -{ - VALUE element, iteration, dest; - rb_scan_args(argc, argv, "02", &element, &iteration); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvMorphologyEx(CVARR(self), CVARR(dest), 0, IPLCONVKERNEL(element), CV_MOP_OPEN, IF_INT(iteration, 1)); - return dest; -} - -/* - * call-seq: - * morpholohy_close([element = nil][,iteration = 1]) -> cvmat - * - * Performs advanced morphological transformations "Closing". - * erode(dilate(src,element),element) - */ -VALUE -rb_morphology_close(int argc, VALUE *argv, VALUE self) -{ - VALUE element, iteration, dest; - rb_scan_args(argc, argv, "02", &element, &iteration); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvMorphologyEx(CVARR(self), CVARR(dest), 0, IPLCONVKERNEL(element), CV_MOP_CLOSE, IF_INT(iteration, 1)); - return dest; -} - -/* - * call-seq: - * morpholohy_gradient([element = nil][,iteration = 1]) -> cvmat - * - * Performs advanced morphological transformations "Morphological gradient". - * dilate(src,element)-erode(src,element) - */ -VALUE -rb_morphology_gradient(int argc, VALUE *argv, VALUE self) -{ - VALUE element, iteration, temp, dest; - rb_scan_args(argc, argv, "02", &element, &iteration); - temp = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvMorphologyEx(CVARR(self), CVARR(dest), CVARR(temp), IPLCONVKERNEL(element), CV_MOP_GRADIENT, IF_INT(iteration, 1)); - return dest; -} - -/* - * call-seq: - * morpholohy_tophat([element = nil][,iteration = 1]) -> cvmat - * - * Performs advanced morphological transformations "tophat". - * src-open(src,element) - */ -VALUE -rb_morphology_tophat(int argc, VALUE *argv, VALUE self) -{ - VALUE element, iteration, dest; - rb_scan_args(argc, argv, "02", &element, &iteration); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvMorphologyEx(CVARR(self), CVARR(dest), 0, IPLCONVKERNEL(element), CV_MOP_TOPHAT, IF_INT(iteration, 1)); - return dest; -} - -/* - * call-seq: - * morpholohy_blackhat([element = nil][,iteration = 1]) -> cvmat - * - * Performs advanced morphological transformations "blackhat". - * close(src,element)-src - */ -VALUE -rb_morphology_blackhat(int argc, VALUE *argv, VALUE self) -{ - VALUE element, iteration, dest; - rb_scan_args(argc, argv, "02", &element, &iteration); - dest = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvMorphologyEx(CVARR(self), CVARR(dest), 0, IPLCONVKERNEL(element), CV_MOP_BLACKHAT, IF_INT(iteration, 1)); - return dest; -} - -/* - * call-seq: - * smooth_blur_no_scale([p1 = 3, p2 = 3]) -> cvmat - * - * Smooths the image by simple blur with no scaling. - * * 8bit unsigned -> return 16bit unsigned - * * 8bit signed -> return 16bit signed - * * 32bit floating point -> return 32bit floating point - * support single-channel image only. - */ -VALUE -rb_smooth_blur_no_scale(int argc, VALUE *argv, VALUE self) -{ - SUPPORT_C1_ONLY(self); - VALUE p1, p2, dest; - rb_scan_args(argc, argv, "02", &p1, &p2); - int type = cvGetElemType(CVARR(self)), dest_type; - switch (CV_MAT_DEPTH(type)) { - case CV_8U: - dest_type = CV_16U; - break; - case CV_8S: - dest_type = CV_16S; - break; - case CV_32F: - dest_type = CV_32F; - break; - default: - rb_raise(rb_eNotImpError, "unsupport format. (support 8bit unsigned/signed or 32bit floating point only)"); - } - dest = new_object(cvGetSize(CVARR(self)), dest_type); - cvSmooth(CVARR(self), CVARR(dest), CV_BLUR_NO_SCALE, IF_INT(p1, 3), IF_INT(p2, 0)); - return dest; -} - -/* - * call-seq: - * smooth_blur([p1 = 3, p2 = 3]) -> cvmat - * - * Smooths the image by simple blur. - * Summation over a pixel p1 x p2 neighborhood with subsequent scaling by 1 / (p1*p2). - */ -VALUE -rb_smooth_blur(int argc, VALUE *argv, VALUE self) -{ - SUPPORT_C1C3_ONLY(self); - VALUE p1, p2, dest; - rb_scan_args(argc, argv, "02", &p1, &p2); - dest = cCvMat::new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvSmooth(CVARR(self), CVARR(dest), CV_BLUR, IF_INT(p1, 3), IF_INT(p2, 0)); - return dest; -} - -/* - * call-seq: - * smooth_gaussian([p1 = 3, p2 = 3, p3 = 0.0, p4 = 0.0]) -> cvmat - * - * Smooths the image by gaussian blur. - * Convolving image with p1 x p2 Gaussian kernel. - * - * p3 may specify Gaussian sigma (standard deviation). - * If it is zero, it is calculated from the kernel size: - * sigma = (n/2 - 1)*0.3 + 0.8, where n = p1 for horizontal kernel, - * n = p2 for vertical kernel. - * - * p4 is in case of non-square Gaussian kernel the parameter. - * It may be used to specify a different (from p3) sigma in the vertical direction. - */ -VALUE -rb_smooth_gaussian(int argc, VALUE *argv, VALUE self) -{ - SUPPORT_C1C3_ONLY(self); - VALUE p1, p2, p3, p4, dest; - rb_scan_args(argc, argv, "04", &p1, &p2, &p3, p4); - dest = cCvMat::new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvSmooth(CVARR(self), CVARR(dest), CV_GAUSSIAN, IF_INT(p1, 3), IF_INT(p2, 0), IF_DBL(p3, 0.0), IF_DBL(p4, 0.0)); - return dest; -} - -/* - * call-seq: - * smooth_median([p1 = 3]) -> cvmat - * - * Smooths the image by median blur. - * Finding median of p1 x p1 neighborhood (i.e. the neighborhood is square). - */ -VALUE -rb_smooth_median(int argc, VALUE *argv, VALUE self) -{ - SUPPORT_8U_ONLY(self); - SUPPORT_C1C3_ONLY(self); - VALUE p1, dest; - rb_scan_args(argc, argv, "01", &p1); - dest = cCvMat::new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvSmooth(CVARR(self), CVARR(dest), CV_MEDIAN, IF_INT(p1, 3)); - return dest; -} - -/* - * call-seq: - * smooth_bilateral([p1 = 3][p2 = 3]) -> cvmat - * - * Smooths the image by bilateral filter. - * Applying bilateral 3x3 filtering with color sigma=p1 and space sigma=p2. - */ -VALUE -rb_smooth_bilateral(int argc, VALUE *argv, VALUE self) -{ - SUPPORT_8U_ONLY(self); - SUPPORT_C1C3_ONLY(self); - VALUE p1, p2, dest; - rb_scan_args(argc, argv, "02", &p1, &p2); - dest = cCvMat::new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvSmooth(CVARR(self), CVARR(dest), CV_BILATERAL, IF_INT(p1, 3), IF_INT(p2, 0)); - return dest; -} - -/* - * call-seq: - * filter2d(kernel[,anchor]) -> cvmat - * - * Convolves image with the kernel. - * Convolution kernel, single-channel floating point matrix (or same depth of self's). - * If you want to apply different kernels to different channels, - * split the image using CvMat#split into separate color planes and process them individually. - */ -VALUE -rb_filter2d(int argc, VALUE *argv, VALUE self) -{ - VALUE kernel, anchor, dest; - rb_scan_args(argc, argv, "11", &kernel, &anchor); - if (!rb_obj_is_kind_of(kernel, cCvMat::rb_class())) - rb_raise(rb_eTypeError, "argument 1 (kernel) should be %s.", rb_class2name(cCvMat::rb_class())); - int type = cvGetElemType(CVARR(kernel)); - dest = cCvMat::new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvFilter2D(CVARR(self), CVARR(dest), CVMAT(kernel), NIL_P(anchor) ? cvPoint(-1,-1) : VALUE_TO_CVPOINT(anchor)); - return dest; -} - -/* - * call-seq: - * copy_make_border_constant(size, offset[,value = CvScalar.new(0)]) - * - * Copies image and makes border around it. - * Border is filled with the fixed value, passed as last parameter of the function. - */ -VALUE -rb_copy_make_border_constant(int argc, VALUE *argv, VALUE self) -{ - VALUE size, offset, value, dest; - rb_scan_args(argc, argv, "21", &size, &offset, &value); - dest = cCvMat::new_object(VALUE_TO_CVSIZE(size), cvGetElemType(CVARR(self))); - cvCopyMakeBorder(CVARR(self), CVARR(dest), VALUE_TO_CVPOINT(offset), IPL_BORDER_CONSTANT, NIL_P(value) ? cvScalar(0) : VALUE_TO_CVSCALAR(value)); - return dest; -} - -/* - * call-seq: - * copy_make_border_replicate(size, offset) - * - * Copies image and makes border around it. - * The pixels from the top and bottom rows, - * the left-most and right-most columns are replicated to fill the border. - */ -VALUE -rb_copy_make_border_replicate(int argc, VALUE *argv, VALUE self) -{ - VALUE size, offset, dest; - rb_scan_args(argc, argv, "20", &size, &offset); - dest = cCvMat::new_object(VALUE_TO_CVSIZE(size), cvGetElemType(CVARR(self))); - cvCopyMakeBorder(CVARR(self), CVARR(dest), VALUE_TO_CVPOINT(offset), IPL_BORDER_REPLICATE); - return dest; -} - -/* - * call-seq: - * integral(need_sqsum = false, need_tilted_sum = false) -> [cvmat, cvmat or nil, cvmat or nil] - * - * Calculates integral images. - * If need_sqsum = true, calculate the integral image for squared pixel values. - * If need_tilted_sum = true, calculate the integral for the image rotated by 45 degrees. - * - * sum(X,Y)=sumxthreshold, max_value[,use_otsu = false]) - * - * Applies fixed-level threshold to array elements. - * - * dst(x,y) = max_value, if src(x,y)>threshold - * 0, otherwise - */ -VALUE -rb_threshold_binary(int argc, VALUE *argv, VALUE self) -{ - VALUE threshold, max_value, use_otsu, dest; - rb_scan_args(argc, argv, "21", &threshold, &max_value, &use_otsu); - dest = cCvMat::new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvThreshold(CVARR(self), CVARR(dest), NUM2DBL(threshold), NUM2DBL(max_value), CV_THRESH_BINARY | (use_otsu == Qtrue ? CV_THRESH_OTSU : 0)); - return dest; -} - -/* - * call-seq: - * threshold_binary_inverse(threshold, max_value[,use_otsu = false]) - * - * Applies fixed-level threshold to array elements. - * - * dst(x,y) = 0, if src(x,y)>threshold - * max_value, otherwise - */ -VALUE -rb_threshold_binary_inverse(int argc, VALUE *argv, VALUE self) -{ - VALUE threshold, max_value, use_otsu, dest; - rb_scan_args(argc, argv, "21", &threshold, &max_value, &use_otsu); - dest = cCvMat::new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvThreshold(CVARR(self), CVARR(dest), NUM2DBL(threshold), NUM2DBL(max_value), CV_THRESH_BINARY_INV | (use_otsu == Qtrue ? CV_THRESH_OTSU : 0)); - return dest; -} - -/* - * call-seq: - * threshold_trunc(threshold[,use_otsu = false]) - * - * Applies fixed-level threshold to array elements. - * - * dst(x,y) = threshold, if src(x,y)>threshold - * src(x,y), otherwise - */ -VALUE -rb_threshold_trunc(int argc, VALUE *argv, VALUE self) -{ - VALUE threshold, use_otsu, dest; - rb_scan_args(argc, argv, "11", &threshold, &use_otsu); - dest = cCvMat::new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvThreshold(CVARR(self), CVARR(dest), NUM2DBL(threshold), 0, CV_THRESH_BINARY_INV | (use_otsu == Qtrue ? CV_THRESH_OTSU : 0)); - return dest; -} - -/* - * call-seq: - * threshold_to_zero(threshold[,use_otsu = false]) - * - * Applies fixed-level threshold to array elements. - * - * dst(x,y) = src(x,y), if src(x,y)>threshold - * 0, otherwise - */ -VALUE -rb_threshold_to_zero(int argc, VALUE *argv, VALUE self) -{ - VALUE threshold, use_otsu, dest; - rb_scan_args(argc, argv, "11", &threshold, &use_otsu); - dest = cCvMat::new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvThreshold(CVARR(self), CVARR(dest), NUM2DBL(threshold), 0, CV_THRESH_TOZERO | (use_otsu == Qtrue ? CV_THRESH_OTSU : 0)); - return dest; -} - -/* - * call-seq: - * threshold_to_zero_inverse(threshold[,use_otsu = false]) - * - * Applies fixed-level threshold to array elements. - * - * dst(x,y) = 0, if src(x,y)>threshold - * src(x,y), otherwise - */ -VALUE -rb_threshold_to_zero_inverse(int argc, VALUE *argv, VALUE self) -{ - VALUE threshold, use_otsu, dest; - rb_scan_args(argc, argv, "11", &threshold, &use_otsu); - dest = cCvMat::new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvThreshold(CVARR(self), CVARR(dest), NUM2DBL(threshold), 0, CV_THRESH_TOZERO_INV | (use_otsu == Qtrue ? CV_THRESH_OTSU : 0)); - return dest; -} - -/* - * call-seq: - * pyr_down([filter = :gaussian_5x5]) -> cvmat - * - * Return downsamples image. - * - * This operation performs downsampling step of Gaussian pyramid decomposition. - * First it convolves source image with the specified filter and then downsamples the image by rejecting even rows and columns. - * - * note: filter - only :gaussian_5x5 is currently supported. - */ -VALUE -rb_pyr_down(int argc, VALUE *argv, VALUE self) -{ - VALUE filter_type, dest; - rb_scan_args(argc, argv, "01", &filter_type); - int filter = CV_GAUSSIAN_5x5; - if (argc > 0) { - switch (TYPE(filter_type)) { - case T_SYMBOL: - // currently suport CV_GAUSSIAN_5x5 only. - break; - default: - rb_raise(rb_eArgError, "argument 1 (filter_type) should be Symbol."); - } - } - CvSize size = cvGetSize(CVARR(self)); - dest = cCvMat::new_object(size.height / 2, size.width / 2, cvGetElemType(CVARR(self))); - cvPyrDown(CVARR(self), CVARR(dest), filter); - return dest; -} - -/* - * call-seq: - * pyr_up([filter = :gaussian_5x5]) -> cvmat - * - * Return upsamples image. - * - * This operation performs up-sampling step of Gaussian pyramid decomposition. - * First it upsamples the source image by injecting even zero rows and columns and then convolves result with the specified filter multiplied by 4 for interpolation. - * So the destination image is four times larger than the source image. - * - * note: filter - only :gaussian_5x5 is currently supported. - */ -VALUE -rb_pyr_up(int argc, VALUE *argv, VALUE self) -{ - VALUE filter_type, dest; - rb_scan_args(argc, argv, "01", &filter_type); - int filter = CV_GAUSSIAN_5x5; - if (argc > 0) { - switch (TYPE(filter_type)) { - case T_SYMBOL: - // currently suport CV_GAUSSIAN_5x5 only. - break; - default: - rb_raise(rb_eArgError, "argument 1 (filter_type) should be Symbol."); - } - } - CvSize size = cvGetSize(CVARR(self)); - dest = cCvMat::new_object(size.height * 2, size.width * 2, cvGetElemType(CVARR(self))); - cvPyrUp(CVARR(self), CVARR(dest), filter); - return dest; -} - -/* - * call-seq: - * flood_fill(seed_point, new_val, lo_diff, up_diff[,flood_fill_option]) -> [cvmat, cvconnectedcomp, iplimage(mask)] - * - * Return image filled a connnected compoment with given color. - * This operation fills a connected component starting from the seed point with the specified color. - * The connectivity is determined by the closeness of pixel values. - * The pixel at (x, y) is considered to belong to the repainted domain if: - * - * src(x',y')-lo_diff<=src(x,y)<=src(x',y')+up_diff, grayscale image, floating range - * src(seed.x,seed.y)-lo<=src(x,y)<=src(seed.x,seed.y)+up_diff, grayscale image, fixed range - * src(x',y')r-lo_diffr<=src(x,y)r<=src(x',y')r+up_diffr and - * src(x',y')g-lo_diffg<=src(x,y)g<=src(x',y')g+up_diffg and - * src(x',y')b-lo_diffb<=src(x,y)b<=src(x',y')b+up_diffb, color image, floating range - * src(seed.x,seed.y)r-lo_diffr<=src(x,y)r<=src(seed.x,seed.y)r+up_diffr and - * src(seed.x,seed.y)g-lo_diffg<=src(x,y)g<=src(seed.x,seed.y)g+up_diffg and - * src(seed.x,seed.y)b-lo_diffb<=src(x,y)b<=src(seed.x,seed.y)b+up_diffb, color image, fixed range - * - * where src(x',y') is value of one of pixel neighbors. - * That is, to be added to the connected component, a pixel's color/brightness should be close enough to: - * * color/brightness of one of its neighbors that are already referred to the connected component in case of floating range - * * color/brightness of the seed point in case of fixed range. - * - * arguments - * * seed_point -The starting point. - * * new_val - New value of repainted domain pixels. - * * lo_diff - Maximal lower brightness/color difference between the currently observed pixel and one of its neighbor belong to the component or seed pixel to add the pixel to component. In case of 8-bit color images it is packed value. - * * up_diff - Maximal upper brightness/color difference between the currently observed pixel and one of its neighbor belong to the component or seed pixel to add the pixel to component. In case of 8-bit color images it is packed value. - * - * and flood_fill_option - * :connectivity => 4 or 8, 4 default - * Connectivity determines which neighbors of a pixel are considered. - * :fixed_range => true or false, false default - * If set the difference between the current pixel and seed pixel is considered, otherwise difference between neighbor pixels is considered (the range is floating). - * :mask_only => true or false, false default - * If set, the function does not fill the image(new_val is ignored), but the fills mask. - * - * note: flood_fill_option's default value is CvMat::FLOOD_FILL_OPTION. - */ -VALUE -rb_flood_fill(int argc, VALUE *argv, VALUE self) -{ - return rb_flood_fill_bang(argc, argv, copy(self)); -} - -/* - * call-seq: - * flood_fill!(seed_point, new_val, lo_diff, up_diff[,flood_fill_option]) -> [self, cvconnectedcomp, iplimage(mask)] - * - * Fills a connected component with given color. - * see CvMat#flood_fill - */ -VALUE -rb_flood_fill_bang(int argc, VALUE *argv, VALUE self) -{ - VALUE seed_point, new_val, lo_diff, up_diff, flood_fill_option, mask, comp; - rb_scan_args(argc, argv, "23", &seed_point, &new_val, &lo_diff, &up_diff, &flood_fill_option); - flood_fill_option = FLOOD_FILL_OPTION(flood_fill_option); - int flags = FF_CONNECTIVITY(flood_fill_option); - if (FF_FIXED_RANGE(flood_fill_option)) { - flags |= CV_FLOODFILL_FIXED_RANGE; - } - if (FF_MASK_ONLY(flood_fill_option)) { - flags |= CV_FLOODFILL_MASK_ONLY; - } - CvSize size = cvGetSize(CVARR(self)); - mask = cIplImage::new_object(size.width + 2, size.height + 2, CV_MAKETYPE(CV_8U, 1)); - comp = cCvConnectedComp::new_object(); - cvFloodFill(CVARR(self), - VALUE_TO_CVPOINT(seed_point), - VALUE_TO_CVSCALAR(new_val), - NIL_P(lo_diff) ? cvScalar(0) : VALUE_TO_CVSCALAR(lo_diff), - NIL_P(lo_diff) ? cvScalar(0) : VALUE_TO_CVSCALAR(up_diff), - CVCONNECTEDCOMP(comp), - flags, - CVARR(mask)); - cvSetImageROI(IPLIMAGE(mask), cvRect(1, 1, size.width, size.height)); - return rb_ary_new3(3, self, comp, mask); -} - -/* - * call-seq: - * find_contours([find_contours_options]) -> cvchain or chcontour or nil - * - * Finds contours in binary image, and return contours as CvContour or CvChain. - * If contours not found, return nil. - * - * flood_fill_option should be Hash include these keys. - * :mode - Retrieval mode. - * :external - retrive only the extreme outer contours - * :list - retrieve all the contours and puts them in the list.(default) - * :ccomp - retrieve all the contours and organizes them into two-level hierarchy: - * top level are external boundaries of the components, second level are bounda boundaries of the holes - * :tree - retrieve all the contours and reconstructs the full hierarchy of nested contours - * Connectivity determines which neighbors of a pixel are considered. - * :method - Approximation method. - * :code - output contours in the Freeman chain code. All other methods output polygons (sequences of vertices). - * :approx_none - translate all the points from the chain code into points; - * :approx_simple - compress horizontal, vertical, and diagonal segments, that is, the function leaves only their ending points;(default) - * :approx_tc89_l1 - * :approx_tc89_kcos - apply one of the flavors of Teh-Chin chain approximation algorithm. - * If set the difference between the current pixel and seed pixel is considered, - * otherwise difference between neighbor pixels is considered (the range is floating). - * :offset - Offset, by which every contour point is shifted. - * This is useful if the contours are extracted from the image ROI - * and then they should be analyzed in the whole image context. Should be CvPoint. - * - * note: find_contours_option's default value is CvMat::FIND_CONTOURS_OPTION. - * - * support single-channel 8bit unsigned image only. - * - * note: Non-zero pixels are treated as 1's, zero pixels remain 0's - * that is image treated as binary. To get such a binary image from grayscale, - * one may use threshold, adaptive_threshold or canny. - */ -VALUE -rb_find_contours(int argc, VALUE *argv, VALUE self) -{ - SUPPORT_8UC1_ONLY(self); - return rb_find_contours_bang(argc, argv, copy(self)); -} - -/* - * call-seq: - * find_contours!([find_contours_options]) -> cvchain or chcontour or nil - * - * Finds contours in binary image. - * The function modifies the source image content. - * (Because the copy is not made, it is slightly faster than find_contours.) - * - * see find_contours - * - * support single-channel 8bit unsigned image only. - */ -VALUE -rb_find_contours_bang(int argc, VALUE *argv, VALUE self) -{ - SUPPORT_8UC1_ONLY(self); - VALUE find_contours_option, klass, element_klass, storage; - rb_scan_args(argc, argv, "01", &find_contours_option); - CvSeq *contour = 0; - find_contours_option = FIND_CONTOURS_OPTION(find_contours_option); - int mode = FC_MODE(find_contours_option); - int method = FC_METHOD(find_contours_option); - int header, header_size, element_size; - if (method == CV_CHAIN_CODE) { - klass = cCvChain::rb_class(); - element_klass = cCvChainCode::rb_class(); - header = CV_SEQ_CHAIN_CONTOUR; - header_size = sizeof(CvChain); - element_size = sizeof(CvChainCode); - } else { - klass = cCvContour::rb_class(); - element_klass = cCvPoint::rb_class(); - header = CV_SEQ_CONTOUR; - header_size = sizeof(CvContour); - element_size = sizeof(CvPoint); - } - storage = cCvMemStorage::new_object(); - if(cvFindContours(CVARR(self), CVMEMSTORAGE(storage), &contour, header, mode, method, FC_OFFSET(find_contours_option)) == 0) - return Qnil; - if(!contour) - contour = cvCreateSeq(header, header_size, element_size, CVMEMSTORAGE(storage)); - return cCvSeq::new_sequence(klass, contour, element_klass, storage); -} - -/* - * call-seq: - * pyr_segmentation(level, threshold1, threshold2) -> [cvmat, cvseq(include cvconnectedcomp)] - * - * Does image segmentation by pyramids. - * The pyramid builds up to the level level. - * The links between any pixel a on leveli and - * its candidate father pixel b on the adjacent level are established if - * p(c(a),c(b)) < threshold1. After the connected components are defined, they are joined into several clusters. Any two segments A and B belong to the same cluster, if - * p(c(A),c(B)) < threshold2. The input image has only one channel, then - * p(c^2,c^2)=|c^2-c^2|. If the input image has three channels (red, green and blue), then - * p(c^2,c^2)=0,3*(c^2 r-c^2 r)+0.59*(c^2 g-c^2 g)+0,11*(c^2 b-c^2 b) . There may be more than one connected component per a cluster. - * - * Return segmented image and sequence of connected components. - * support single-channel or 3-channel 8bit unsigned image only - */ -VALUE -rb_pyr_segmentation(int argc, VALUE *argv, VALUE self) -{ - SUPPORT_8U_ONLY(self); - SUPPORT_C1C3_ONLY(self); - VALUE level, threshold1, threshold2, storage, dest; - rb_scan_args(argc, argv, "30", &level, &threshold1, &threshold2); - IplImage *src = IPLIMAGE(self); - int l = FIX2INT(level); - double t1 = NUM2DBL(threshold1), t2 = NUM2DBL(threshold2); - if (!(l >0)) - rb_raise(rb_eArgError, "argument 1 (level) should be > 0."); - if(((src->width | src->height) & ((1 << l) -1 )) != 0) - rb_raise(rb_eArgError, "bad image size on level %d.", FIX2INT(level)); - if (t1 < 0) - rb_raise(rb_eArgError, "argument 2 (threshold for establishing the link) should be >= 0."); - if (t2 < 0) - rb_raise(rb_eArgError, "argument 3 (threshold for the segments clustering) should be >= 0."); - dest = cIplImage::new_object(cvGetSize(src), cvGetElemType(src)); - CvSeq *comp = 0; - storage = cCvMemStorage::new_object(); - - cvPyrSegmentation(src, - IPLIMAGE(dest), - CVMEMSTORAGE(storage), - &comp, - l, t1, t2); - if(!comp) - comp = cvCreateSeq(CV_SEQ_CONNECTED_COMP, sizeof(CvSeq), sizeof(CvConnectedComp), CVMEMSTORAGE(storage)); - return rb_ary_new3(2, dest, cCvSeq::new_sequence(cCvSeq::rb_class(), comp, cCvConnectedComp::rb_class(), storage)); -} - -/* - * call-seq: - * pyr_mean_shift_filtering(sp, sr[,max_level = 1][termcrit = CvTermCriteria.new(5,1)]) -> cvmat - * - * Does meanshift image segmentation. - * - * sp - The spatial window radius. - * sr - The color window radius. - * max_level - Maximum level of the pyramid for the segmentation. - * termcrit - Termination criteria: when to stop meanshift iterations. - * - * This method is implements the filtering stage of meanshift segmentation, - * that is, the output of the function is the filtered "posterized" image with color gradients and fine-grain texture flattened. - * At every pixel (X,Y) of the input image (or down-sized input image, see below) - * the function executes meanshift iterations, that is, the pixel (X,Y) neighborhood in the joint space-color hyperspace is considered: - * {(x,y): X-sp≤x≤X+sp && Y-sp≤y≤Y+sp && ||(R,G,B)-(r,g,b)|| ≤ sr}, - * where (R,G,B) and (r,g,b) are the vectors of color components at (X,Y) and (x,y), - * respectively (though, the algorithm does not depend on the color space used, - * so any 3-component color space can be used instead). - * Over the neighborhood the average spatial value (X',Y') - * and average color vector (R',G',B') are found and they act as the neighborhood center on the next iteration: - * (X,Y)~(X',Y'), (R,G,B)~(R',G',B'). - * After the iterations over, the color components of the initial pixel (that is, the pixel from where the iterations started) - * are set to the final value (average color at the last iteration): - * I(X,Y) <- (R*,G*,B*). - * Then max_level > 0, the gaussian pyramid of max_level+1 levels is built, - * and the above procedure is run on the smallest layer. - * After that, the results are propagated to the larger layer and the iterations are run again - * only on those pixels where the layer colors differ much (>sr) from the lower-resolution layer, - * that is, the boundaries of the color regions are clarified. - * - * Note, that the results will be actually different from the ones obtained by running the meanshift procedure on the whole original image (i.e. when max_level==0). - */ -VALUE -rb_pyr_mean_shift_filtering(int argc, VALUE *argv, VALUE self) -{ - VALUE spatial_window_radius, color_window_radius, max_level, termcrit, dest; - rb_scan_args(argc, argv, "22", &spatial_window_radius, &color_window_radius, &max_level, &termcrit); - dest = cCvMat::new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvPyrMeanShiftFiltering(CVARR(self), CVARR(dest), - NUM2DBL(spatial_window_radius), - NUM2DBL(color_window_radius), - IF_INT(max_level, 1), - NIL_P(termcrit) ? cvTermCriteria(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 5, 1) : VALUE_TO_CVTERMCRITERIA(termcrit)); - return dest; -} - -/* - * call-seq: - * watershed -> cvmat(mean markers:cv32s) - * - * Does watershed segmentation. - */ -VALUE -rb_watershed(VALUE self) -{ - VALUE markers = cCvMat::new_object(cvGetSize(CVARR(self)), CV_32SC1); - cvZero(CVARR(markers)); - cvWatershed(CVARR(self), CVARR(markers)); - return markers; -} - -/* - * call-seq: - * moments -> array(include CvMoments) - * - * Calculates moments. - */ -VALUE -rb_moments(int argc, VALUE *argv, VALUE self) -{ - VALUE is_binary, moments; - rb_scan_args(argc, argv, "01", &is_binary); - IplImage image = *IPLIMAGE(self); - int cn = CV_MAT_CN(cvGetElemType(CVARR(self))); - moments = rb_ary_new(); - for(int i = 1; i <= cn; i++) { - cvSetImageCOI(&image, i); - rb_ary_push(moments, cCvMoments::new_object(&image, TRUE_OR_FALSE(is_binary, 0))); - } - return moments; -} - -/* - * call-seq: - * hough_line_standard(rho, theta, threshold) -> cvseq(include CvLine) - * - * Finds lines in binary image using standard(classical) Hough transform. - * * rho - Distance resolution in pixel-related units. - * * theta - Angle resolution measured in radians. - * * threshold - Threshold parameter. A line is returned by the function if the corresponding accumulator value is greater than threshold. - */ -VALUE -rb_hough_lines_standard(int argc, VALUE *argv, VALUE self) -{ - SUPPORT_8UC1_ONLY(self); - VALUE rho, theta, threshold, storage; - rb_scan_args(argc, argv, "30", &rho, &theta, &threshold); - storage = cCvMemStorage::new_object(); - CvSeq *seq = cvHoughLines2(CVARR(copy(self)), CVMEMSTORAGE(storage), - CV_HOUGH_STANDARD, NUM2DBL(rho), NUM2DBL(theta), NUM2INT(threshold)); - return cCvSeq::new_sequence(cCvSeq::rb_class(), seq, cCvLine::rb_class(), storage); -} - -/* - * call-seq: - * hough_line_probabilistic(rho, theta, threshold, min_length, max_gap) -> cvseq(include CvTwoPoints) - * - * Finds lines in binary image using probabilistic Hough transform. - * * rho - Distance resolution in pixel-related units. - * * theta - Angle resolution measured in radians. - * * threshold - Threshold parameter. A line is returned by the function if the corresponding accumulator value is greater than threshold. - * * min_length - The minimum line length. - * * max_gap - The maximum gap between line segments lieing on the same line to treat them as the single line segment (i.e. to join them). - */ -VALUE -rb_hough_lines_probabilistic(int argc, VALUE *argv, VALUE self) -{ - SUPPORT_8UC1_ONLY(self); - VALUE rho, theta, threshold, p1, p2, storage; - rb_scan_args(argc, argv, "50", &rho, &theta, &threshold, &p1, &p2); - storage = cCvMemStorage::new_object(); - CvSeq *seq = cvHoughLines2(CVARR(copy(self)), CVMEMSTORAGE(storage), - CV_HOUGH_PROBABILISTIC, NUM2DBL(rho), NUM2DBL(theta), NUM2INT(threshold), - NUM2DBL(p1), NUM2DBL(p2)); - return cCvSeq::new_sequence(cCvSeq::rb_class(), seq, cCvTwoPoints::rb_class(), storage); -} - -/* - * call-seq: - * hough_line_multi_scale(rho, theta, threshold, div_rho, div_theta) -> cvseq(include CvLine) - * - * Finds lines in binary image using multi-scale variant of classical Hough transform. - * * rho - Distance resolution in pixel-related units. - * * theta - Angle resolution measured in radians. - * * threshold - Threshold parameter. A line is returned by the function if the corresponding accumulator value is greater than threshold. - * * div_rho = divisor for distance resolution rho. - * * div_theta = divisor for angle resolution theta. - */ -VALUE -rb_hough_lines_multi_scale(int argc, VALUE *argv, VALUE self) -{ - SUPPORT_8UC1_ONLY(self); - VALUE rho, theta, threshold, p1, p2, storage; - rb_scan_args(argc, argv, "50", &rho, &theta, &threshold, &p1, &p2); - storage = cCvMemStorage::new_object(); - CvSeq *seq = cvHoughLines2(CVARR(copy(self)), CVMEMSTORAGE(storage), - CV_HOUGH_MULTI_SCALE, NUM2DBL(rho), NUM2DBL(theta), NUM2INT(threshold), - NUM2DBL(p1), NUM2DBL(p2)); - return cCvSeq::new_sequence(cCvSeq::rb_class(), seq, cCvLine::rb_class(), storage); -} - -/* - * call-seq: - * hough_circles_gradient(dp, min_dist, threshold_canny, threshold_accumulate, min_radius = 0, max_radius = max(width,height)) -> cvseq(include CvCircle32f) - * - * Finds circles in grayscale image using Hough transform. - */ -VALUE -rb_hough_circles_gradient(int argc, VALUE *argv, VALUE self) -{ - SUPPORT_8UC1_ONLY(self); - VALUE dp, min_dist, threshold_canny, threshold_accumulate, min_radius, max_radius, storage; - rb_scan_args(argc, argv, "24", &dp, &min_dist, &threshold_canny, &threshold_accumulate, &min_radius, &max_radius); - storage = cCvMemStorage::new_object(); - CvSeq *seq = cvHoughCircles(CVARR(self), CVMEMSTORAGE(storage), - CV_HOUGH_GRADIENT, NUM2DBL(dp), NUM2DBL(min_dist), - NUM2DBL(threshold_canny), NUM2DBL(threshold_accumulate), - IF_INT(min_radius, 0), IF_INT(max_radius, 0)); - return cCvSeq::new_sequence(cCvSeq::rb_class(), seq, cCvCircle32f::rb_class(), storage); -} - -/* - * call-seq: - * inpaint_ns(mask, radius) -> cvmat - * - * Inpaints the selected region in the image by Navier-Stokes based method. - * The radius of circlular neighborhood of each point inpainted that is considered by the algorithm. - */ -VALUE -rb_inpaint_ns(VALUE self, VALUE mask, VALUE radius) -{ - SUPPORT_8U_ONLY(self); - SUPPORT_C1C3_ONLY(self); - VALUE dest; - if (!(rb_obj_is_kind_of(mask, cCvMat::rb_class())) || cvGetElemType(CVARR(mask)) != CV_8UC1) - rb_raise(rb_eTypeError, "argument 1 (mask) should be mask image."); - dest = cCvMat::new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvInpaint(CVARR(self), CVARR(mask), CVARR(dest), NUM2DBL(radius), CV_INPAINT_NS); - return dest; -} - -/* - * call-seq: - * inpaint_telea(mask, radius) -> cvmat - * - * Inpaints the selected region in the image by The method by Alexandru Telea's method. - * The radius of circlular neighborhood of each point inpainted that is considered by the algorithm. - */ -VALUE -rb_inpaint_telea(VALUE self, VALUE mask, VALUE radius) -{ - SUPPORT_8U_ONLY(self); - SUPPORT_C1C3_ONLY(self); - VALUE dest; - if (!(rb_obj_is_kind_of(mask, cCvMat::rb_class())) || cvGetElemType(CVARR(mask)) != CV_8UC1) - rb_raise(rb_eTypeError, "argument 1 (mask) should be mask image."); - dest = cCvMat::new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvInpaint(CVARR(self), CVARR(mask), CVARR(dest), NUM2DBL(radius), CV_INPAINT_TELEA); - return dest; -} - -/* - * call-seq: - * equalize_hist - cvmat - * - * Equalize histgram of grayscale of image. - * - * equalizes histogram of the input image using the following algorithm: - * 1. calculate histogram H for src. - * 2. normalize histogram, so that the sum of histogram bins is 255. - * 3. compute integral of the histogram: - * H’(i) = sum0≤j≤iH(j) - * 4. transform the image using H’ as a look-up table: dst(x,y)=H’(src(x,y)) - * The algorithm normalizes brightness and increases contrast of the image. - * - * support single-channel 8bit image (grayscale) only. - */ -VALUE -rb_equalize_hist(VALUE self) -{ - SUPPORT_8UC1_ONLY(self); - VALUE dest = cCvMat::new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); - cvEqualizeHist(CVARR(self), CVARR(dest)); - return dest; -} - -/* - * call-seq: - * match_template(template[,method = :sqdiff]) -> cvmat(result) - * - * Compares template against overlapped image regions. - - * method is specifies the way the template must be compared with image regions. - * method should be following symbol. (see CvMat::MATCH_TEMPLATE_METHOD 's key and value.) - * - * * :sqdiff - * R(x,y)=sumx',y'[T(x',y')-I(x+x',y+y')]2 - * * :sqdiff_normed - * R(x,y)=sumx',y'[T(x',y')-I(x+x',y+y')]2/sqrt[sumx',y'T(x',y')2*sumx',y'I(x+x',y+y')2] - * * :ccorr - * R(x,y)=sumx',y'[T(x',y')*I(x+x',y+y')] - * * :ccorr_normed - * R(x,y)=sumx',y'[T(x',y')*I(x+x',y+y')]/sqrt[sumx',y'T(x',y')2*sumx',y'I(x+x',y+y')2] - * * :ccoeff - * R(x,y)=sumx',y'[T'(x',y')*I'(x+x',y+y')], - * where T'(x',y')=T(x',y') - 1/(w*h)*sumx",y"T(x",y") - * I'(x+x',y+y')=I(x+x',y+y') - 1/(w*h)*sumx",y"I(x+x",y+y") - * * :ccoeff_normed - * R(x,y)=sumx',y'[T'(x',y')*I'(x+x',y+y')]/sqrt[sumx',y'T'(x',y')2*sumx',y'I'(x+x',y+y')2] - * - * After the match_template finishes comparison, the best matches can be found as global - * minimums (:sqdiff*) or maximums(:ccorr* or :ccoeff*) using minmax function. - * In case of color image and template summation in both numerator and each sum in denominator - * is done over all the channels (and separate mean values are used for each channel). - */ -VALUE -rb_match_template(int argc, VALUE *argv, VALUE self) -{ - VALUE templ, method, result; - rb_scan_args(argc, argv, "11", &templ, &method); - if (!(rb_obj_is_kind_of(templ, cCvMat::rb_class()))) - rb_raise(rb_eTypeError, "argument 1 (template) should be %s.", rb_class2name(cCvMat::rb_class())); - if (cvGetElemType(CVARR(self)) != cvGetElemType(CVARR(templ))) - rb_raise(rb_eTypeError, "template should be same type of self."); - CvSize src_size = cvGetSize(CVARR(self)), template_size = cvGetSize(CVARR(self)); - result = cCvMat::new_object(cvSize(src_size.width - template_size.width + 1, - src_size.height - template_size.height + 1), - CV_32FC1); - cvMatchTemplate(CVARR(self), CVARR(templ), CVARR(result), CVMETHOD("MATCH_TEMPLATE_METHOD", CV_TM_SQDIFF)); - return result; -} - -/* - * call-seq: - * match_shapes_i1(object) -> float - * - * Compares two shapes(self and object). object should be CvMat or CvContour. - * - * A ~ object1, B - object2): - * I1(A,B)=sumi=1..7abs(1/mAi - 1/mBi) - */ -VALUE -rb_match_shapes_i1(int argc, VALUE *argv, VALUE self) -{ - VALUE object; - rb_scan_args(argc, argv, "10", &object); - if ((!(rb_obj_is_kind_of(object, cCvMat::rb_class()))) && (!(rb_obj_is_kind_of(object, cCvContour::rb_class())))) - rb_raise(rb_eTypeError, "argument 1 (shape) should be %s or %s", rb_class2name(cCvMat::rb_class()), rb_class2name(cCvContour::rb_class())); - return rb_float_new(cvMatchShapes(CVARR(self), CVARR(object), CV_CONTOURS_MATCH_I1)); -} - -/* - * call-seq: - * match_shapes_i2(object) -> float - * - * Compares two shapes(self and object). object should be CvMat or CvContour. - * - * A ~ object1, B - object2): - * I2(A,B)=sumi=1..7abs(mAi - mBi) - */ -VALUE -rb_match_shapes_i2(int argc, VALUE *argv, VALUE self) -{ - VALUE object; - rb_scan_args(argc, argv, "10", &object); - if ((!(rb_obj_is_kind_of(object, cCvMat::rb_class()))) && (!(rb_obj_is_kind_of(object, cCvContour::rb_class())))) - rb_raise(rb_eTypeError, "argument 1 (shape) should be %s or %s", rb_class2name(cCvMat::rb_class()), rb_class2name(cCvContour::rb_class())); - return rb_float_new(cvMatchShapes(CVARR(self), CVARR(object), CV_CONTOURS_MATCH_I2)); -} - -/* - * call-seq: - * match_shapes_i3(object) -> float - * - * Compares two shapes(self and object). object should be CvMat or CvContour. - * - * A ~ object1, B - object2): - * I3(A,B)=sumi=1..7abs(mAi - mBi)/abs(mAi) - */ -VALUE -rb_match_shapes_i3(int argc, VALUE *argv, VALUE self) -{ - VALUE object; - rb_scan_args(argc, argv, "10", &object); - if ((!(rb_obj_is_kind_of(object, cCvMat::rb_class()))) && (!(rb_obj_is_kind_of(object, cCvContour::rb_class())))) - rb_raise(rb_eTypeError, "argument 1 (shape) should be %s or %s", rb_class2name(cCvMat::rb_class()), rb_class2name(cCvContour::rb_class())); - return rb_float_new(cvMatchShapes(CVARR(self), CVARR(object), CV_CONTOURS_MATCH_I3)); -} - - -/* - * call-seq: - * mean_shift(window, criteria) -> comp - * - * Implements CAMSHIFT object tracking algrorithm. - * First, it finds an object center using mean_shift and, after that, - * calculates the object size and orientation. - */ -VALUE -rb_mean_shift(VALUE self, VALUE window, VALUE criteria) -{ - VALUE comp = cCvConnectedComp::new_object(); - cvMeanShift(CVARR(self), VALUE_TO_CVRECT(window), VALUE_TO_CVTERMCRITERIA(criteria), CVCONNECTEDCOMP(comp)); - return comp; -} - -/* - * call-seq: - * cam_shift(window, criteria) -> [comp, box] - * - * Implements CAMSHIFT object tracking algrorithm. First, it finds an object center using cvMeanShift and, - * after that, calculates the object size and orientation. The function returns number of iterations made - * within cvMeanShift. - */ -VALUE -rb_cam_shift(VALUE self, VALUE window, VALUE criteria) -{ - VALUE comp, box; - comp = cCvConnectedComp::new_object(); - box = cCvBox2D::new_object(); - cvCamShift(CVARR(self), VALUE_TO_CVRECT(window), VALUE_TO_CVTERMCRITERIA(criteria), CVCONNECTEDCOMP(comp), CVBOX2D(box)); - return rb_ary_new3(2, comp, box); -} - -/* - * call-seq: - * snake_image(points, alpha, beta, gamma, window, criteria[, calc_gradient = true]) -> cvseq(pointset) - * - * Updates snake in order to minimize its total energy that is a sum of internal energy - * that depends on contour shape (the smoother contour is, the smaller internal energy is) - * and external energy that depends on the energy field and reaches minimum at the local energy - * extremums that correspond to the image edges in case of image gradient. - - * The parameter criteria.epsilon is used to define the minimal number of points that must be moved - * during any iteration to keep the iteration process running. - * - * If at some iteration the number of moved points is less than criteria.epsilon or - * the function performed criteria.max_iter iterations, the function terminates. - * - * points - * Contour points (snake). - * alpha - * Weight[s] of continuity energy, single float or array of length floats, one per each contour point. - * beta - * Weight[s] of curvature energy, similar to alpha. - * gamma - * Weight[s] of image energy, similar to alpha. - * window - * Size of neighborhood of every point used to search the minimum, both win.width and win.height must be odd. - * criteria - * Termination criteria. - * calc_gradient - * Gradient flag. If not 0, the function calculates gradient magnitude for every image pixel and consideres - * it as the energy field, otherwise the input image itself is considered. - */ -VALUE -rb_snake_image(int argc, VALUE *argv, VALUE self) -{ - VALUE points, alpha, beta, gamma, window, criteria, calc_gradient, storage; - rb_scan_args(argc, argv, "43", &points, &alpha, &beta, &gamma, &window, &criteria, &calc_gradient); - CvPoint *pointset = 0; - CvSeq *seq = 0; - int length = CVPOINTS_FROM_POINT_SET(points, &pointset); - int coeff = (TYPE(alpha) == T_ARRAY || TYPE(beta) == T_ARRAY || TYPE(gamma) == T_ARRAY) ? CV_ARRAY : CV_VALUE; - float *a = 0, *b = 0, *c = 0; - IplImage stub; - if(coeff == CV_VALUE){ - a = ALLOC(float); - a[0] = (float)NUM2DBL(alpha); - b = ALLOC(float); - b[0] = (float)NUM2DBL(beta); - c = ALLOC(float); - c[0] = (float)NUM2DBL(gamma); - }else{ // CV_ARRAY - rb_raise(rb_eNotImpError, ""); - // todo - } - CvSize w = VALUE_TO_CVSIZE(window); - CvTermCriteria tc = VALUE_TO_CVTERMCRITERIA(criteria); - cvSnakeImage(cvGetImage(CVARR(self), &stub), pointset, length, - a, b, c, coeff, w, tc, IF_BOOL(calc_gradient, 1, 0, 1)); - storage = cCvMemStorage::new_object(); - seq = cvCreateSeq(CV_SEQ_POINT_SET, sizeof(CvSeq), sizeof(CvPoint), CVMEMSTORAGE(storage)); - cvSeqPushMulti(seq, pointset, length); - return cCvSeq::new_sequence(cCvSeq::rb_class(), seq, cCvPoint::rb_class(), storage); -} - -/* - * call-seq: - * optical_flow_hs(prev[,velx = nil][,vely = nil][,options]) -> [cvmat, cvmat] - * - * Calculates optical flow for two images (previous -> self) using Horn & Schunck algorithm. - * Return horizontal component of the optical flow and vertical component of the optical flow. - * prev is previous image - * velx is previous velocity field of x-axis, and vely is previous velocity field of y-axis. - * - * options - * * :lambda -> should be Float (default is 0.0005) - * Lagrangian multiplier. - * * :criteria -> should be CvTermCriteria object (default is CvTermCriteria(1, 0.001)) - * Criteria of termination of velocity computing. - * note: option's default value is CvMat::OPTICAL_FLOW_HS_OPTION. - * - * sample code - * velx, vely = nil, nil - * while true - * current = capture.query - * velx, vely = current.optical_flow_hs(prev, velx, vely) if prev - * prev = current - * emd - */ -VALUE -rb_optical_flow_hs(int argc, VALUE *argv, VALUE self) -{ - SUPPORT_8UC1_ONLY(self); - VALUE prev, velx, vely, options; - int use_previous = 0; - rb_scan_args(argc, argv, "13", &prev, &velx, &vely, &options); - options = OPTICAL_FLOW_HS_OPTION(options); - if (!rb_obj_is_kind_of(prev, cCvMat::rb_class())) - rb_raise(rb_eTypeError, "argument 1 (previous image) should be %s", rb_class2name(cCvMat::rb_class())); - if (NIL_P(velx) && NIL_P(vely)) { - velx = cCvMat::new_object(cvGetSize(CVARR(self)), CV_MAKETYPE(CV_32F, 1)); - vely = cCvMat::new_object(cvGetSize(CVARR(self)), CV_MAKETYPE(CV_32F, 1)); - } else { - if (rb_obj_is_kind_of(velx, cCvMat::rb_class()) && rb_obj_is_kind_of(vely, cCvMat::rb_class())) - use_previous = 1; - else - rb_raise(rb_eArgError, "Necessary to give both argument 2(previous velocity field x) and argument 3(previous velocity field y)"); - } - cvCalcOpticalFlowHS(CVARR(prev), CVARR(self), use_previous, CVARR(velx), CVARR(vely), HS_LAMBDA(options), HS_CRITERIA(options)); - return rb_ary_new3(2, velx, vely); -} - -/* - * call-seq: - * optical_flow_lk(prev, win_size) -> [cvmat, cvmat] - * - * Calculates optical flow for two images (previous -> self) using Lucas & Kanade algorithm - * Return horizontal component of the optical flow and vertical component of the optical flow. - * - * win_size is size of the averaging window used for grouping pixels. - */ -VALUE -rb_optical_flow_lk(int argc, VALUE *argv, VALUE self) -{ - SUPPORT_8UC1_ONLY(self); - VALUE prev, win_size, velx, vely; - rb_scan_args(argc, argv, "20", &prev, &win_size); - if (!rb_obj_is_kind_of(prev, cCvMat::rb_class())) - rb_raise(rb_eTypeError, "argument 1 (previous image) should be %s", rb_class2name(cCvMat::rb_class())); - velx = cCvMat::new_object(cvGetSize(CVARR(self)), CV_MAKETYPE(CV_32F, 1)); - vely = cCvMat::new_object(cvGetSize(CVARR(self)), CV_MAKETYPE(CV_32F, 1)); - cvCalcOpticalFlowLK(CVARR(prev), CVARR(self), VALUE_TO_CVSIZE(win_size), CVARR(velx), CVARR(vely)); - return rb_ary_new3(2, velx, vely); -} - -/* - * call-seq: - * optical_flow_bm(prev[,velx = nil][,vely = nil][,option]) -> [cvmat, cvmat] - * - * Calculates optical flow for two images (previous -> self) using block matching method. - * Return horizontal component of the optical flow and vertical component of the optical flow. - * prev is previous image. - * velx is previous velocity field of x-axis, and vely is previous velocity field of y-axis. - * - * options - * * :block_size -> should be CvSize (default is CvSize(4,4)) - * Size of basic blocks that are compared. - * * :shift_size -> should be CvSize (default is CvSize(1,1)) - * Block coordinate increments. - * * :max_range -> should be CvSize (default is CVSize(4,4)) - * Size of the scanned neighborhood in pixels around block. - * note: option's default value is CvMat::OPTICAL_FLOW_BM_OPTION. - * - * Velocity is computed for every block, but not for every pixel, - * so velocity image pixels correspond to input image blocks. - * input/output velocity field's size should be (self.width / block_size.width)x(self.height / block_size.height). - * e.g. image.size is 320x240 and block_size is 4x4, velocity field's size is 80x60. - * - */ -VALUE -rb_optical_flow_bm(int argc, VALUE *argv, VALUE self) -{ - SUPPORT_8UC1_ONLY(self); - VALUE prev, velx, vely, options; - int use_previous = 0; - rb_scan_args(argc, argv, "13", &prev, &velx, &vely, &options); - options = OPTICAL_FLOW_BM_OPTION(options); - CvSize - image_size = cvGetSize(CVARR(self)), - block_size = BM_BLOCK_SIZE(options), - shift_size = BM_SHIFT_SIZE(options), - max_range = BM_MAX_RANGE(options), - velocity_size = cvSize(image_size.width / block_size.width, image_size.height / block_size.height); - if (NIL_P(velx) && NIL_P(vely)) { - velx = cCvMat::new_object(velocity_size, CV_MAKETYPE(CV_32F, 1)); - vely = cCvMat::new_object(velocity_size, CV_MAKETYPE(CV_32F, 1)); - } else { - if (rb_obj_is_kind_of(velx, cCvMat::rb_class()) && rb_obj_is_kind_of(vely, cCvMat::rb_class())) - use_previous = 1; - else - rb_raise(rb_eArgError, "Necessary to give both argument 2(previous velocity field x) and argument 3(previous velocity field y)"); - } - cvCalcOpticalFlowBM(CVARR(prev), CVARR(self), - block_size, shift_size, max_range, use_previous, - CVARR(velx), CVARR(vely)); - return rb_ary_new3(2, velx, vely); -} - -/* - * call-seq: - * CvMat.find_fundamental_mat_7point(points1, points2[,options = {}]) -> fundamental_matrix(cvmat) or nil - * - * Calculates fundamental matrix from corresponding points, use for 7-point algorism. Return fundamental matrix(9x3). - * points1 and points2 should be 2x7 or 3x7 single-channel, or 1x7 multi-channel matrix. - * option should be Hash include these keys. - * :with_status (true or false) - * If set true, return fundamental_matrix and status. [fundamental_matrix, status] - * Otherwise return fundamental matrix only(default). - * - * note: option's default value is CvMat::FIND_FUNDAMENTAL_MAT_OPTION. - * note: 9x3 fundamental matrix means 3x3 three fundamental matrices. - */ -VALUE -rb_find_fundamental_mat_7point(int argc, VALUE *argv, VALUE klass) -{ - VALUE points1, points2, option, fundamental_matrix, status; - int num = 0; - rb_scan_args(argc, argv, "21", &points1, &points2, &option); - option = FIND_FUNDAMENTAL_MAT_OPTION(option); - fundamental_matrix = cCvMat::new_object(9, 3, CV_32FC1); - if(FFM_WITH_STATUS(option)){ - status = cCvMat::new_object(cvGetSize(CVARR(points1)), CV_8UC1); - num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), CV_FM_7POINT, 0, 0, CVMAT(status)); - return rb_ary_new3(2, fundamental_matrix, status); - }else{ - num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), CV_FM_7POINT, 0, 0, NULL); - return fundamental_matrix; - } -} - - -/* - * call-seq: - * CvMat.find_fundamental_mat_8point(points1, points2[,options = {}]) -> fundamental_matrix(cvmat) or nil - * - * Calculates fundamental matrix from corresponding points, use for 8-point algorism. - * points1 and points2 should be 2x7 or 3x7 single-channel, or 1x7 multi-channel matrix. - * option should be Hash include these keys. - * :with_status (true or false) - * If set true, return fundamental_matrix and status. [fundamental_matrix, status] - * Otherwise return fundamental matrix only(default). - * - * note: option's default value is CvMat::FIND_FUNDAMENTAL_MAT_OPTION. - */ -VALUE -rb_find_fundamental_mat_8point(int argc, VALUE *argv, VALUE klass) -{ - VALUE points1, points2, option, fundamental_matrix, status; - int num = 0; - rb_scan_args(argc, argv, "21", &points1, &points2, &option); - option = FIND_FUNDAMENTAL_MAT_OPTION(option); - fundamental_matrix = cCvMat::new_object(3, 3, CV_32FC1); - if(FFM_WITH_STATUS(option)){ - status = cCvMat::new_object(cvGetSize(CVARR(points1)), CV_8UC1); - num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), CV_FM_8POINT, 0, 0, CVMAT(status)); - return num == 0 ? Qnil : rb_ary_new3(2, fundamental_matrix, status); - }else{ - num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), CV_FM_8POINT, 0, 0, NULL); - return num == 0 ? Qnil : fundamental_matrix; - } -} - -/* - * call-seq: - * CvMat.find_fundamental_mat_ransac(points1, points2[,options = {}]) -> fundamental_matrix(cvmat) or nil - * - * Calculates fundamental matrix from corresponding points, use for RANSAC algorism. - * points1 and points2 should be 2x7 or 3x7 single-channel, or 1x7 multi-channel matrix. - * option should be Hash include these keys. - * :with_status (true or false) - * If set true, return fundamental_matrix and status. [fundamental_matrix, status] - * Otherwise return fundamental matrix only(default). - * :maximum_distance - * The maximum distance from point to epipolar line in pixels, beyond which the point is considered an outlier - * and is not used for computing the final fundamental matrix. Usually it is set to 0.5 or 1.0. - * :desirable_level - * It denotes the desirable level of confidence that the matrix is correct. - * - * note: option's default value is CvMat::FIND_FUNDAMENTAL_MAT_OPTION. - */ -VALUE -rb_find_fundamental_mat_ransac(int argc, VALUE *argv, VALUE klass) -{ - VALUE points1, points2, option, fundamental_matrix, status; - int num = 0; - rb_scan_args(argc, argv, "21", &points1, &points2, &option); - option = FIND_FUNDAMENTAL_MAT_OPTION(option); - fundamental_matrix = cCvMat::new_object(3, 3, CV_32FC1); - if(FFM_WITH_STATUS(option)){ - status = cCvMat::new_object(cvGetSize(CVARR(points1)), CV_8UC1); - num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), CV_FM_RANSAC, FFM_MAXIMUM_DISTANCE(option), FFM_DESIRABLE_LEVEL(option), CVMAT(status)); - return num == 0 ? Qnil : rb_ary_new3(2, fundamental_matrix, status); - }else{ - num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), CV_FM_RANSAC, FFM_MAXIMUM_DISTANCE(option), FFM_DESIRABLE_LEVEL(option), NULL); - return num == 0 ? Qnil : fundamental_matrix; - } -} - -/* - * call-seq: - * CvMat.find_fundamental_mat_lmeds(points1, points2[,options = {}]) -> fundamental_matrix(cvmat) or nil - * - * Calculates fundamental matrix from corresponding points, use for LMedS algorism. - * points1 and points2 should be 2x7 or 3x7 single-channel, or 1x7 multi-channel matrix. - * option should be Hash include these keys. - * :with_status (true or false) - * If set true, return fundamental_matrix and status. [fundamental_matrix, status] - * Otherwise return fundamental matrix only(default). - * :maximum_distance - * The maximum distance from point to epipolar line in pixels, beyond which the point is considered an outlier - * and is not used for computing the final fundamental matrix. Usually it is set to 0.5 or 1.0. - * :desirable_level - * It denotes the desirable level of confidence that the matrix is correct. - * - * note: option's default value is CvMat::FIND_FUNDAMENTAL_MAT_OPTION. - */ -VALUE -rb_find_fundamental_mat_lmeds(int argc, VALUE *argv, VALUE klass) -{ - VALUE points1, points2, option, fundamental_matrix, status; - int num = 0; - rb_scan_args(argc, argv, "21", &points1, &points2, &option); - option = FIND_FUNDAMENTAL_MAT_OPTION(option); - fundamental_matrix = cCvMat::new_object(3, 3, CV_32FC1); - if(FFM_WITH_STATUS(option)){ - status = cCvMat::new_object(cvGetSize(CVARR(points1)), CV_8UC1); - num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), CV_FM_LMEDS, FFM_MAXIMUM_DISTANCE(option), FFM_DESIRABLE_LEVEL(option), CVMAT(status)); - return num == 0 ? Qnil : rb_ary_new3(2, fundamental_matrix, status); - }else{ - num = cvFindFundamentalMat(CVMAT(points1), CVMAT(points2), CVMAT(fundamental_matrix), CV_FM_LMEDS, FFM_MAXIMUM_DISTANCE(option), FFM_DESIRABLE_LEVEL(option), NULL); - return num == 0 ? Qnil : fundamental_matrix; - } -} - -/* - * call-seq: - * CvMat.compute_correspond_epilines(points, which_image, fundamental_matrix) -> correspondent_lines(cvmat) - * - * For points in one image of stereo pair computes the corresponding epilines in the other image. - * Finds equation of a line that contains the corresponding point (i.e. projection of the same 3D point) - * in the other image. Each line is encoded by a vector of 3 elements l=[a,b,c]T, so that: - * lT*[x, y, 1]T=0, - * or - * a*x + b*y + c = 0 - * From the fundamental matrix definition (see cvFindFundamentalMatrix discussion), line l2 for a point p1 in the first image (which_image=1) can be computed as: - * l2=F*p1 - * and the line l1 for a point p2 in the second image (which_image=1) can be computed as: - * l1=FT*p2 - * Line coefficients are defined up to a scale. They are normalized (a2+b2=1) are stored into correspondent_lines. - */ -VALUE -rb_compute_correspond_epilines(VALUE klass, VALUE points, VALUE which_image, VALUE fundamental_matrix) -{ - VALUE correspondent_lines; - CvSize size = cvGetSize(CVARR(points)); - int n; - if(size.width <= 3 && size.height >= 7) - n = size.height; - else if(size.height <= 3 && size.width >= 7) - n = size.width; - else - rb_raise(rb_eTypeError, "input points should 2xN, Nx2 or 3xN, Nx3 matrix(N >= 7)."); - correspondent_lines = cCvMat::new_object(n, 3, CV_32F); - cvComputeCorrespondEpilines(CVMAT(points), FIX2INT(which_image), CVMAT(fundamental_matrix), CVMAT(correspondent_lines)); - return correspondent_lines; -} - -VALUE -new_object(int rows, int cols, int type) -{ - return OPENCV_OBJECT(rb_klass, cvCreateMat(rows, cols, type)); -} - -VALUE -new_object(CvSize size, int type) -{ - return OPENCV_OBJECT(rb_klass, cvCreateMat(size.height, size.width, type)); -} - -__NAMESPACE_END_OPENCV -__NAMESPACE_END_CVMAT diff --git a/ext/cvmatnd.cpp b/ext/cvmatnd.cpp deleted file mode 100644 index 6a2d3102..00000000 --- a/ext/cvmatnd.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/*********************************************************** - - cvmatnd.cpp - - - $Author: lsxi $ - - Copyright (C) 2007 Masakazu Yonekura - -************************************************************/ -#include "cvmatnd.h" -/* - * Document-class: OpenCV::CvMatND - * - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVMATND - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * cvmat = rb_define_class_under(opencv, "CvMat", rb_cObject); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(), cvmat = cCvMat::rb_class(); - - rb_klass = rb_define_class_under(opencv, "CvMatND", cvmat); -} - -__NAMESPACE_END_CVMATND -__NAMESPACE_END_OPENCV - diff --git a/ext/cvmatnd.h b/ext/cvmatnd.h deleted file mode 100644 index 75165c76..00000000 --- a/ext/cvmatnd.h +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************************ - - cvmatnd.h - - - $Author: lsxi $ - - Copyright (C) 2007 Masakazu Yonekura - -************************************************************/ -#ifndef RUBY_OPENCV_CVMATND_H -#define RUBY_OPENCV_CVMATND_H - -#include "opencv.h" - -#define __NAMESPACE_BEGIN_CVMATND namespace cCvMatND{ -#define __NAMESPACE_END_CVMATND } - -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVMATND - -VALUE rb_class(); - -void define_ruby_class(); - -__NAMESPACE_END_CVMATND -__NAMESPACE_END_OPENCV - -#endif // RUBY_OPENCV_CVMATND_H diff --git a/ext/cvseq.cpp b/ext/cvseq.cpp deleted file mode 100644 index be6f22dd..00000000 --- a/ext/cvseq.cpp +++ /dev/null @@ -1,583 +0,0 @@ -/************************************************************ - - cvseq.cpp - - - $Author: lsxi $ - - Copyright (C) 2005-2006 Masakazu Yonekura - -************************************************************/ -#include "cvseq.h" -/* - * Document-class: OpenCV::CvSeq - * - * Generic Sequence class. CvSeq has the method like Array (push, pop, select, etc...). - * But, CvSeq cannot store the object of a different class. - * When storing object in CvSeq, conversion is automatically tried, - * and the object occurs the error if it cannot be done. - * - * e.g. - * seq = CvSeq.new(CvPoint) # Argument mean "this sequence contain only this class's object" - * seq.push(CvPoint.new(0, 0)) # => it's ok - * seq.push("hello") # => try convert "hello" to CvPoint. but can't do it. raise error. - * - * If the sequecne contain object of class A. - * When storing object(named "obj") of class B to the sequence. - * Try automatically : A.from_B(obj) => object of class A. - * - * CvSeq has the circulation structure internally. - * That is, when the sequence has three values ("a","b","c"), - * seq[0] and seq[3] are same "a", and seq[-1] and seq[2] are same "c". - * - * The sequence might have another sequence outside. see below. - * Each sequece has h_prev, h_next, v_prev, v_next method. - * If the adjoining sequence exists, each method return the adjoining sequence. - * Otherwise return nil. - * - * link:../images/CvSeq_relationmap.png - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVSEQ - -// contain sequence-block class -st_table *seqblock_klass = st_init_numtable(); - -VALUE -seqblock_class(void *ptr) -{ - VALUE klass; - if(!st_lookup(seqblock_klass, (st_data_t)ptr, (st_data_t*)&klass)){ - rb_raise(rb_eTypeError, "Invalid sequence error."); - } - return klass; -} - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void -define_ruby_class() -{ - if(rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - rb_klass = rb_define_class_under(opencv, "CvSeq", rb_cObject); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); - rb_define_method(rb_klass, "total", RUBY_METHOD_FUNC(rb_total), 0); - rb_define_alias(rb_klass, "length", "total"); - rb_define_alias(rb_klass, "size", "total"); - rb_define_method(rb_klass, "empty?", RUBY_METHOD_FUNC(rb_empty_q), 0); - rb_define_method(rb_klass, "[]", RUBY_METHOD_FUNC(rb_aref), 1); - rb_define_method(rb_klass, "first", RUBY_METHOD_FUNC(rb_first), 0); - rb_define_method(rb_klass, "last", RUBY_METHOD_FUNC(rb_last), 0); - rb_define_method(rb_klass, "index", RUBY_METHOD_FUNC(rb_index), 1); - - rb_define_method(rb_klass, "h_prev", RUBY_METHOD_FUNC(rb_h_prev), 0); - rb_define_method(rb_klass, "h_next", RUBY_METHOD_FUNC(rb_h_next), 0); - rb_define_method(rb_klass, "v_prev", RUBY_METHOD_FUNC(rb_v_prev), 0); - rb_define_method(rb_klass, "v_next", RUBY_METHOD_FUNC(rb_v_next), 0); - - rb_define_method(rb_klass, "push", RUBY_METHOD_FUNC(rb_push), -2); - rb_define_alias(rb_klass, "<<", "push"); - rb_define_method(rb_klass, "pop", RUBY_METHOD_FUNC(rb_pop), 0); - rb_define_method(rb_klass, "unshift", RUBY_METHOD_FUNC(rb_unshift), -2); - rb_define_alias(rb_klass, "push_front", "unshift"); - rb_define_method(rb_klass, "shift", RUBY_METHOD_FUNC(rb_shift), 0); - rb_define_alias(rb_klass, "pop_front", "shift"); - rb_define_method(rb_klass, "each", RUBY_METHOD_FUNC(rb_each), 0); - rb_define_method(rb_klass, "each_index", RUBY_METHOD_FUNC(rb_each_index), 0); - rb_define_method(rb_klass, "each_with_index", RUBY_METHOD_FUNC(rb_each_with_index), 0); - rb_define_method(rb_klass, "insert", RUBY_METHOD_FUNC(rb_insert), 2); - rb_define_method(rb_klass, "remove", RUBY_METHOD_FUNC(rb_remove), 1); - rb_define_method(rb_klass, "clear", RUBY_METHOD_FUNC(rb_clear), 0); - - rb_define_alias(rb_klass, "delete_at", "remove"); -} - -VALUE -rb_allocate(VALUE klass) -{ - return Data_Wrap_Struct(klass, mark_root_object, free, 0); -} - -void -free(void *ptr) -{ - if(ptr){ - unresist_object(ptr); - st_delete(seqblock_klass, (st_data_t*)&ptr, 0); - } -} - -void -resist_class_information_of_sequence(CvSeq *seq, VALUE klass) -{ - st_insert(seqblock_klass, (st_data_t)seq, (st_data_t)klass); -} - -/* - * call-seq: - * CvSeq.new(type[,storage]) - * - * Return a new CvSeq. type should be following classes. - * - * * CvIndex - * * CvPoint - */ -VALUE -rb_initialize(int argc, VALUE *argv, VALUE self) -{ - VALUE klass, storage; - rb_scan_args(argc, argv, "11", &klass, &storage); - if(!rb_obj_is_kind_of(klass, rb_cClass)) - rb_raise(rb_eTypeError, "argument 1 (sequence-block class) should be %s.", rb_class2name(rb_cClass)); - CvSeq *seq = 0; - storage = CHECK_CVMEMSTORAGE(storage); - int type = 0, size = 0; - if(klass == cCvIndex::rb_class()){ - type = CV_SEQ_ELTYPE_INDEX; - size = sizeof(CvIndex); - }else if(klass == cCvPoint::rb_class()){ - type = CV_SEQ_ELTYPE_POINT; - size = sizeof(CvPoint); - }else if(klass == cCvPoint2D32f::rb_class()){ - type = CV_SEQ_ELTYPE_POINT; - size = sizeof(CvPoint2D32f); - }else if(klass == cCvPoint3D32f::rb_class()){ - type = CV_SEQ_ELTYPE_POINT3D; - size = sizeof(CvPoint3D32f); - } - auto_extend(self); - // todo: more various class will be support. - if(!size) - rb_raise(rb_eTypeError, "unsupport %s class for sequence-block.", rb_class2name(klass)); - seq = cvCreateSeq(type, sizeof(CvSeq), size, CVMEMSTORAGE(storage)); - DATA_PTR(self) = seq; - resist_root_object(seq, storage); - // resist class information of this sequence. - st_insert(seqblock_klass, (st_data_t)seq, (st_data_t)klass); - return self; -} - -/* - * call-seq: - * total -> int - * - * Return total number of sequence-block. - */ -VALUE -rb_total(VALUE self) -{ - return INT2FIX(CVSEQ(self)->total); -} - -/* - * call-seq: - * empty? -> true or false. - * - * Return true if contain no object, otherwize return false. - */ -VALUE -rb_empty_q(VALUE self) -{ - return CVSEQ(self)->total == 0 ? Qtrue : Qfalse; -} - -/* - * call-seq: - * [index] -> obj or nil - * - * Return sequence-block at index. - */ -VALUE -rb_aref(VALUE self, VALUE index) -{ - CvSeq *seq = CVSEQ(self); - if(!(seq->total > 0)) - return Qnil; - return REFER_OBJECT(seqblock_class(seq), cvGetSeqElem(seq, NUM2INT(index) % seq->total), self); -} - -/* - * call-seq: - * first -> obj or nil - * - * Return first sequence-block. - */ -VALUE -rb_first(VALUE self) -{ - CvSeq *seq = CVSEQ(self); - if(!(seq->total > 0)) - return Qnil; - return REFER_OBJECT(seqblock_class(seq), cvGetSeqElem(seq, 0), self); -} - -/* - * call-seq: - * last -> obj or nil - * - * Return last sequence-block. - */ -VALUE -rb_last(VALUE self) -{ - CvSeq *seq = CVSEQ(self); - if(!(seq->total > 0)) - return Qnil; - return REFER_OBJECT(seqblock_class(seq), cvGetSeqElem(seq, -1), self); -} - -/*when storing it in CvSeq. - * call-seq: - * index(obj) -> int or nil - * - * Return the index of the first object in self. Return nil if no match is found. - */ -VALUE -rb_index(VALUE self, VALUE object) -{ - CvSeq *seq = CVSEQ(self); - int index; - if(CLASS_OF(object) == seqblock_class(seq)){ - index = cvSeqElemIdx(seq, DATA_PTR(object)); - if(!(index < 0)) - return INT2FIX(index); - }else{ - rb_warn("sequence-block class unmatch."); - } - return Qnil; -} - -/* - * call-seq: - * h_prev -> seq or nil - * - * Return the sequence horizontally located in previous. - * Return nil if not existing. - */ -VALUE -rb_h_prev(VALUE self) -{ - CvSeq *seq = CVSEQ(self); - if (seq->h_prev) { - return new_sequence(CLASS_OF(self), seq->h_prev, seqblock_class(seq), lookup_root_object(seq)); - //new_sequence(seq->h_prev, CLASS_OF(self), seqblock_class(seq), lookup_root_object(seq)); - } else - return Qnil; -} - -/* - * call-seq: - * h_next -> seq or nil - * - * Return the sequence horizontally located in next. - * Return nil if not existing. - */ -VALUE -rb_h_next(VALUE self) -{ - CvSeq *seq = CVSEQ(self); - if (seq->h_next) { - return new_sequence(CLASS_OF(self), seq->h_next, seqblock_class(seq), lookup_root_object(seq)); - //new_sequence(seq->h_next, CLASS_OF(self), seqblock_class(seq), lookup_root_object(seq)); - } else - return Qnil; -} - -/* - * call-seq: - * v_prev -> seq or nil - * - * Return the sequence vertically located in previous. - * Return nil if not existing. - */ -VALUE -rb_v_prev(VALUE self) -{ - CvSeq *seq = CVSEQ(self); - if (seq->v_prev) { - return new_sequence(CLASS_OF(self), seq->v_prev, seqblock_class(seq), lookup_root_object(seq)); - } else - return Qnil; -} - -/* - * call-seq: - * v_prev -> seq or nil - * - * Return the sequence vertically located in next. - * Return nil if not existing. - */ -VALUE -rb_v_next(VALUE self) -{ - CvSeq *seq = CVSEQ(self); - if (seq->v_next) { - return new_sequence(CLASS_OF(self), seq->v_next, seqblock_class(seq), lookup_root_object(seq)); - } else - return Qnil; -} - -/* - * call-seq: - * push(obj, ...) -> self - * - * Append - Pushes the given object(s) on the end of this sequence. This expression return the sequence itself, - * so several append may be chainded together. - */ -VALUE -rb_push(VALUE self, VALUE args) -{ - CvSeq *seq = CVSEQ(self); - VALUE klass = seqblock_class(seq), object; - void *buffer = 0; - for(int i = 0; i < RARRAY(args)->len; i++){ - object = RARRAY(args)->ptr[i]; - if(CLASS_OF(object) == klass){ - cvSeqPush(seq, DATA_PTR(object)); - }else if(rb_obj_is_kind_of(object, rb_klass) && CLASS_OF(object) == klass){ // object is CvSeq - buffer = cvCvtSeqToArray(CVSEQ(object), cvAlloc(CVSEQ(object)->total * CVSEQ(object)->elem_size)); - cvSeqPushMulti(seq, buffer, CVSEQ(object)->total); - cvFree((void**)&buffer); - }else{ - object = CONVERT(object, klass); - cvSeqPush(seq, DATA_PTR(object)); - } - } - return self; -} - -/* - * call-seq: - * pop -> obj or nil - * - * Remove the last sequence-block from self and return it, - * or nil if the sequence is empty. - */ -VALUE -rb_pop(VALUE self) -{ - CvSeq *seq = CVSEQ(self); - if(!(seq->total > 0)){ - return Qnil; - } - VALUE object = GENERIC_OBJECT(seqblock_class(seq), malloc(seq->elem_size)); - cvSeqPop(seq, DATA_PTR(object)); - return object; -} - -/* - * call-seq: - * clear -> self - * - * Clears sequence. Removes all elements from the sequence. - */ -VALUE -rb_clear(VALUE self) -{ - cvClearSeq(CVSEQ(self)); - return self; -} - -/* - * call-seq: - * unshift -> self - * - * Prepends objects to the front of sequence. other elements up one. - */ -VALUE -rb_unshift(VALUE self, VALUE args) -{ - CvSeq *seq = CVSEQ(self); - VALUE klass = seqblock_class(seq), object; - void *buffer = 0; - for(int i = 0; i < RARRAY(args)->len; i++){ - object = RARRAY(args)->ptr[i]; - if(CLASS_OF(object) == klass){ - cvSeqPushFront(seq, DATA_PTR(object)); - }else if(rb_obj_is_kind_of(object, rb_klass) && CLASS_OF(object) == klass){ - buffer = cvCvtSeqToArray(CVSEQ(object), cvAlloc(CVSEQ(object)->total * CVSEQ(object)->elem_size)); - cvSeqPushMulti(seq, buffer, CVSEQ(object)->total, 1); - cvFree((void**)&buffer); - }else{ - object = CONVERT(object, klass); - cvSeqPushFront(seq, DATA_PTR(object)); - } - } - return self; -} - -/* - * call-seq: - * shift -> obj or nil - * - * Returns the first element of self and removes it (shifting all other elements down by one). Returns nil if the array is empty. - */ -VALUE -rb_shift(VALUE self) -{ - CvSeq *seq = CVSEQ(self); - if(!(seq->total > 0)){ - return Qnil; - } - VALUE object = GENERIC_OBJECT(seqblock_class(seq), malloc(seq->elem_size)); - cvSeqPopFront(seq, DATA_PTR(object)); - return object; -} - -/* - * call-seq: - * each{|obj| ... } -> self - * - * Calls block once for each sequence-block in self, - * passing that sequence-block as a parameter. - * seq = CvSeq.new(CvIndex) - * seq.push(5, 6, 7) - * seq.each{|x| print x, " -- " - * produces: - * 5 -- 6 -- 7 -- - */ -VALUE -rb_each(VALUE self) -{ - CvSeq *seq = CVSEQ(self); - if(seq->total > 0){ - VALUE klass = seqblock_class(seq); - for(int i = 0; i < seq->total; i++){ - rb_yield(REFER_OBJECT(klass, cvGetSeqElem(seq, i), self)); - } - } - return self; -} - -/* - * call-seq: - * each_index{|index| ... } -> self - * - * Same as CvSeq#each, but passes the index of the element instead of the element itself. - */ -VALUE -rb_each_index(VALUE self) -{ - CvSeq *seq = CVSEQ(self); - for(int i = 0; i < seq->total; i++) - rb_yield(INT2FIX(i)); - return self; -} - -/* - * call-seq: - * each_with_index{|obj, i| ... } -> self - * - * Calls block with two arguments, the sequence-block and its index, for each sequence-block in sequence. - */ -VALUE -rb_each_with_index(VALUE self) -{ - CvSeq *seq = CVSEQ(self); - VALUE klass = seqblock_class(seq); - for(int i = 0; i < seq->total; i++) - rb_yield_values(2, REFER_OBJECT(klass, cvGetSeqElem(seq, i), self), INT2FIX(i)); - return self; -} - -/* - * call-seq: - * insert(index,obj) -> self - * - * Inserts the given values before element with the given index (which may be negative). - */ -VALUE -rb_insert(VALUE self, VALUE index, VALUE object) -{ - Check_Type(index, T_FIXNUM); - CvSeq *seq = CVSEQ(self); - VALUE klass = seqblock_class(seq); - if(CLASS_OF(object) != klass) - object = CONVERT(object, klass); - cvSeqInsert(seq, FIX2INT(index), DATA_PTR(object)); - return self; -} - -/* - * call-seq: - * remove(index) -> obj or nil - * - * Deletes the elements at the specified index. - */ -VALUE -rb_remove(VALUE self, VALUE index) -{ - cvSeqRemove(CVSEQ(self), FIX2INT(index)); - return self; -} - -/* - * call-seq: - * clone - * - * Return copy of sequence. - */ -VALUE -rb_clone(VALUE self) -{ - CvSeq *seq = CVSEQ(self); - VALUE storage = cCvMemStorage::new_object(); - return new_sequence(CLASS_OF(self), cvCloneSeq(seq), seqblock_class(seq), storage); -} - -/* -VALUE -new_object(CvSeq *seq, VALUE klass) -{ - VALUE storage = cCvMemStorage::new_object(); - VALUE object = REFER_OBJECT(rb_klass, seq, storage); - st_insert(seqblock_klass, (st_data_t)seq, (st_data_t)klass); - return object; -} - -VALUE -new_object(CvSeq *seq, VALUE klass, VALUE storage) -{ - VALUE object = REFER_OBJECT(rb_klass, seq, storage); - st_insert(seqblock_klass, (st_data_t)seq, (st_data_t)klass); - return object; -} -*/ - - -VALUE -new_sequence(VALUE klass, CvSeq *seq, VALUE element_klass, VALUE storage) -{ - resist_root_object(seq, storage); - if (!NIL_P(element_klass)) - st_insert(seqblock_klass, (st_data_t)seq, (st_data_t)element_klass); - VALUE object = Data_Wrap_Struct(klass, mark_root_object, free, seq); - auto_extend(object); - return object; -} - -VALUE -auto_extend(VALUE object) -{ - CvSeq *seq = CVSEQ(object); - if(CV_IS_SEQ_POINT_SET(seq)){ - rb_extend_object(object, mPointSet::rb_module()); - } - return object; -} - -__NAMESPACE_END_CVSEQ -__NAMESPACE_END_OPENCV diff --git a/ext/cvset.cpp b/ext/cvset.cpp deleted file mode 100644 index ea17615a..00000000 --- a/ext/cvset.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/************************************************************ - - cvseq.cpp - - - $Author: lsxi $ - - Copyright (C) 2005-2006 Masakazu Yonekura - -************************************************************/ -#include "cvset.h" -/* - * Document-class: OpenCV::CvSet - * - * Collection of nodes. - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVSET - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void -define_ruby_class() -{ - if(rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * cvseq = rb_define_class_under(opencv, "CvSeq", rb_cObject); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(), cvseq = cCvSeq::rb_class(); - rb_klass = rb_define_class_under(opencv, "CvSet", cvseq); - rb_define_method(rb_klass, "active_count", RUBY_METHOD_FUNC(rb_active_count), 0); - rb_define_method(rb_klass, "free?", RUBY_METHOD_FUNC(rb_free_q), 0); -} - -/* - * ? - */ -VALUE -rb_active_count(VALUE self) -{ - return INT2FIX(CVSET(self)->active_count); -} - -/* - * ? - */ -VALUE -rb_free_q(VALUE self) -{ - return CVSET(self)->free_elems->flags < 0 ? Qtrue : Qfalse; -} - -__NAMESPACE_END_CVSET -__NAMESPACE_END_OPENCV diff --git a/ext/cvset.h b/ext/cvset.h deleted file mode 100644 index 6861dd08..00000000 --- a/ext/cvset.h +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************************ - - cvset.h - - - $Author: lsxi $ - - Copyright (C) 2005-2006 Masakazu Yonekura - -************************************************************/ -#ifndef RUBY_OPENCV_CVSET_H -#define RUBY_OPENCV_CVSET_H - -#include "opencv.h" - -#define __NAMESPACE_BEGIN_CVSET namespace cCvSet{ -#define __NAMESPACE_END_CVSET } - -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVSET - -VALUE rb_class(); -void define_ruby_class(); - -VALUE rb_active_count(VALUE self); -VALUE rb_free_q(VALUE self); - -__NAMESPACE_END_CVSET - -inline CvSet* -CVSET(VALUE object) -{ - CvSet *ptr; - Data_Get_Struct(object, CvSet, ptr); - return ptr; -} - -__NAMESPACE_END_OPENCV - -#endif // RUBY_OPENCV_CVSET_H diff --git a/ext/cvslice.cpp b/ext/cvslice.cpp deleted file mode 100644 index a6cd31b4..00000000 --- a/ext/cvslice.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/************************************************************ - - cvslice.cpp - - - $Author: lsxi $ - - Copyright (C) 2005-2006 Masakazu Yonekura - -************************************************************/ -#include "cvslice.h" -/* - * Document-class: OpenCV::CvClice - * - * C structure is here, very simple. - * typdef struct CvSlice{ - * int start_index; - * int end_index; - * }CvSlice; - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVSLICE - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - rb_klass = rb_define_class_under(opencv, "CvSlice", rb_cObject); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_singleton_method(rb_klass, "compatible?", RUBY_METHOD_FUNC(rb_compatible_q), 1); - rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), 2); -} - -/* - * call-seq: - * compatible?(obj) - * - * same Object#kind_of(Range) - */ -VALUE -rb_compatible_q(VALUE klass, VALUE object) -{ - return rb_obj_is_kind_of(object, rb_cRange); -} - -VALUE -rb_allocate(VALUE klass) -{ - CvSlice *ptr; - return Data_Make_Struct(klass, CvSlice, 0, -1, ptr); -} - -/* - * call-seq: - * new(start, end) - * - * Create new slice object. - */ -VALUE -rb_initialize(VALUE self, VALUE start, VALUE end) -{ - CVSLICE(self)->start_index = NUM2INT(start); - CVSLICE(self)->end_index = NUM2INT(end); - return self; -} - -__NAMESPACE_END_CVSLICE -__NAMESPACE_END_OPENCV diff --git a/ext/cvsparsemat.cpp b/ext/cvsparsemat.cpp deleted file mode 100644 index 5b9ab0f2..00000000 --- a/ext/cvsparsemat.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/*********************************************************** - - cvsparse.cpp - - - $Author: lsxi $ - - Copyright (C) 2007 Masakazu Yonekura - -************************************************************/ -#include "cvsparsemat.h" -/* - * Document-class: OpenCV::CvSparseMat - * - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVSPARSEMAT - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * cvmat = rb_define_class_under(opencv, "CvMat", rb_cObject); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(), cvmat = cCvMat::rb_class(); - - rb_klass = rb_define_class_under(opencv, "CvSparseMat", cvmat); -} - -__NAMESPACE_END_CVSPARSEMAT -__NAMESPACE_END_OPENCV - diff --git a/ext/cvsparsemat.h b/ext/cvsparsemat.h deleted file mode 100644 index 21338e68..00000000 --- a/ext/cvsparsemat.h +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************************ - - cvsparsemat.h - - - $Author: lsxi $ - - Copyright (C) 2005-2006 Masakazu Yonekura - -************************************************************/ -#ifndef RUBY_OPENCV_CVSPARSEMAT_H -#define RUBY_OPENCV_CVSPARSEMAT_H - -#include "opencv.h" - -#define __NAMESPACE_BEGIN_CVSPARSEMAT namespace cCvSparseMat{ -#define __NAMESPACE_END_CVSPARSEMAT } - -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVSPARSEMAT - -VALUE rb_class(); - -void define_ruby_class(); - -__NAMESPACE_END_CVSPARSEMAT -__NAMESPACE_END_OPENCV - -#endif // RUBY_OPENCV_CVSPARSEMAT_H diff --git a/ext/cvvector.cpp b/ext/cvvector.cpp deleted file mode 100644 index e1760dff..00000000 --- a/ext/cvvector.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/************************************************************ - - cvvector.cpp - - - $Author: lsxi $ - - Copyright (C) 2005-2006 Masakazu Yonekura - -************************************************************/ -#include "cvvector.h" -/* - * Document-class: OpenCV::CvVector - * - * 2D vector (X axis and Y axis) - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVVECTOR - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - rb_klass = rb_define_class_under(opencv, "CvVector", rb_cObject); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_singleton_method(rb_klass, "compatible?", RUBY_METHOD_FUNC(rb_compatible_q), 1); - rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); - rb_define_method(rb_klass, "x", RUBY_METHOD_FUNC(rb_x), 0); - rb_define_method(rb_klass, "x=", RUBY_METHOD_FUNC(rb_set_x), 1); - rb_define_method(rb_klass, "y", RUBY_METHOD_FUNC(rb_y), 0); - rb_define_method(rb_klass, "y=", RUBY_METHOD_FUNC(rb_set_y), 1); - - rb_define_method(rb_klass, "to_s", RUBY_METHOD_FUNC(rb_to_s), 0); - rb_define_method(rb_klass, "to_ary", RUBY_METHOD_FUNC(rb_to_ary), 0); -} - -/* - * call-seq: - * combatible?(obj) - * - * Return compatibility to CvVector. Return true if object have method #x and #y. - * - * For example. - * class MyVector - * def x - * 1.0 - * end - * def y - * 2.0 - * end - * end - * mv = MyVector.new - * CvVector.compatible?(mv) #=> true - * CvVector.new(mv) #=> same as CvVector(1.0, 2.0) - */ -VALUE -rb_compatible_q(VALUE klass, VALUE object) -{ - return (rb_respond_to(object, rb_intern("x")) && rb_respond_to(object, rb_intern("y"))) ? Qtrue : Qfalse; -} - -VALUE -rb_allocate(VALUE klass) -{ - CvVector *ptr; - return Data_Make_Struct(klass, CvVector, 0, -1, ptr); -} - -/* - * call-seq: - * new -> CvVector.new(0.0, 0.0) - * new(obj) -> CvVector.new(obj.x.to_f, obj.y.to_f) - * new(x, y) - * - * Create new 2D-vector, (x, y). - * - * new() is same as new(0, 0) - * - * new(obj) is same as new(obj.x.to_f, obj.y.to_f) - */ -VALUE -rb_initialize(int argc, VALUE *argv, VALUE self) -{ - VALUE obj, x, y; - switch (argc) { - case 0: - break; - case 1: - obj = argv[0]; - if (rb_compatible_q(rb_klass, obj)) { - CVVECTOR(self)->x = NUM2INT(rb_funcall(rb_funcall(obj, rb_intern("x"), 0), rb_intern("to_i"), 0)); - CVVECTOR(self)->y = NUM2INT(rb_funcall(rb_funcall(obj, rb_intern("y"), 0), rb_intern("to_i"), 0)); - }else{ - rb_raise(rb_eArgError, "object is not compatible %s.", rb_class2name(rb_klass)); - } - break; - case 2: - x = argv[0], y = argv[1]; - CVVECTOR(self)->x = NUM2INT(x); - CVVECTOR(self)->y = NUM2INT(y); - break; - default: - rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc); - } - return Qnil; -} - -/* - * Return parameter on vector of x-axis. - */ -VALUE -rb_x(VALUE self) -{ - return INT2FIX(CVVECTOR(self)->x); -} - -/* - * call-seq: - * x = val - * - * Set vector of x-axis, return self. - */ -VALUE -rb_set_x(VALUE self, VALUE x) -{ - CVVECTOR(self)->x = NUM2INT(x); - return self; -} - -/* - * Return parameter on vector of y-axis. - */ -VALUE -rb_y(VALUE self) -{ - return INT2FIX(CVVECTOR(self)->y); -} - -/* - * call-seq: - * y = val - * - * Set vector of y-axis, return self. - */ -VALUE -rb_set_y(VALUE self, VALUE y) -{ - CVVECTOR(self)->y = NUM2INT(y); - return self; -} - -/* - * call-seq: - * to_s -> "" - * - * Return x and y by String. - */ -VALUE -rb_to_s(VALUE self) -{ - const int i = 4; - VALUE str[i]; - str[0] = rb_str_new2("<%s:(%d,%d)>"); - str[1] = rb_str_new2(rb_class2name(CLASS_OF(self))); - str[2] = rb_x(self); - str[3] = rb_y(self); - return rb_f_sprintf(i, str); -} - -/* - * call-seq: - * to_ary -> [x, y] - * - * Return x and y by Array. - */ -VALUE -rb_to_ary(VALUE self) -{ - return rb_ary_new3(2, rb_x(self), rb_y(self)); -} - -VALUE -new_object(CvVector point) -{ - VALUE object = rb_allocate(rb_klass); - *CVVECTOR(object) = point; - return object; -} - -__NAMESPACE_END_CVVECTOR -__NAMESPACE_END_OPENCV diff --git a/ext/cvvector.h b/ext/cvvector.h deleted file mode 100644 index f2c51b29..00000000 --- a/ext/cvvector.h +++ /dev/null @@ -1,54 +0,0 @@ -/************************************************************ - - cvvector.h - - - $Author: lsxi $ - - Copyright (C) 2007 Masakazu Yonekura - -************************************************************/ -#ifndef RUBY_OPENCV_CVVECTOR_H -#define RUBY_OPENCV_CVVECTOR_H - -#include "opencv.h" - -#define __NAMESPACE_BEGIN_CVVECTOR namespace cCvVector{ -#define __NAMESPACE_END_CVVECTOR } - -typedef struct CvVector{ - float x; - float y; -} CvVector; - -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_CVVECTOR - -VALUE rb_class(); - -void define_ruby_class(); - -VALUE rb_compatible_q(VALUE klass, VALUE object); - -VALUE rb_allocate(VALUE klass); -VALUE rb_initialize(int argc, VALUE *argv, VALUE self); -VALUE rb_x(VALUE self); -VALUE rb_set_x(VALUE self, VALUE x); -VALUE rb_y(VALUE self); -VALUE rb_set_y(VALUE self, VALUE y); - -VALUE rb_to_s(VALUE self); -VALUE rb_to_ary(VALUE self); - -VALUE new_object(CvVector vector); - -__NAMESPACE_END_CVVECTOR - -inline CvVector *CVVECTOR(VALUE object){ - CvVector *ptr; - Data_Get_Struct(object, CvVector, ptr); - return ptr; -} - -__NAMESPACE_END_OPENCV - -#endif // RUBY_OPENCV_CVVECTOR_H diff --git a/ext/extconf.rb b/ext/extconf.rb deleted file mode 100755 index 274e04d0..00000000 --- a/ext/extconf.rb +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env ruby -#/usr/local/bin/ruby -=begin -create Makefile script for Ruby/OpenCV - -usage : ruby extconf.rb - make && make install - -VC : ruby extconf.rb - nmake -=end -require "mkmf" - -# option "opencv" -# extconf.rb --with-opencv-lib=/path/to/opencv/lib -# extconf.rb --with-opencv-include=/path/to/opencv/include - -dir_config("opencv", "/usr/local/include/opencv", "/usr/local/lib") -if CONFIG["arch"].include?("darwin") - dir_config("ffcall", "/opt/local/include", "/opt/local/lib") -else - dir_config("ffcall", "/usr/local/include", "/usr/local/lib") -end - -opencv_libraries = ["cxcore", "cv", "highgui"] - -puts ">> check require libraries..." -case CONFIG["arch"] -when /mswin32/ - have_library("msvcrt", nil) - opencv_libraries.each{|lib| - have_library(lib) - } -else - opencv_libraries.each{|lib| - raise "lib#{lib} not found." unless have_library(lib) - } - #have_library("ml") - have_library("stdc++") -end - -# check require headers -puts ">> check require headers..." -opencv_libraries.map{|lib| "#{lib}.h"}.each{|header| - raise "#{header} not found." unless have_header(header) -} -#have_header("ml.h") -have_header("stdarg.h") - -# check require functions. -# todo - -# optional libraies check. -puts ">> ----- optional -----" -puts ">> check ffcall..." -# check ffcall -if have_library("callback") && have_header("callback.h") - puts ">> support OpenCV::GUI" -else - puts ">> ! unsupport OpenCV::GUI (if need it. install ffcall)" - puts "http://www.haible.de/bruno/packages-ffcall.html" -end - -# step-final. create Makefile -create_makefile("opencv") diff --git a/ext/iplimage.cpp b/ext/iplimage.cpp deleted file mode 100644 index fe7d3234..00000000 --- a/ext/iplimage.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/************************************************************ - - iplimage.cpp - - - $Author: lsxi $ - - Copyright (C) 2005-2006 Masakazu Yonekura - -************************************************************/ -#include "iplimage.h" -/* - * Document-class: OpenCV::IplImage - * - * IPL(Intel Image Processing Library) Image class. - * - * IplImage is subclass of CvMat. IplImage support ROI(region of interest) and COI(color of interest). - * Most of CvMat method support ROI, and some of CvMat method support COI. - * - * =What is ROI? - * region of interest. - * - * =What is COI? - * color of interest. - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_IPLIMAGE - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * cvmat = rb_define_class_under(opencv, "CvMat", rb_cObject); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - VALUE cvmat = cCvMat::rb_class(); - rb_klass = rb_define_class_under(opencv, "IplImage", cvmat); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_singleton_method(rb_klass, "load", RUBY_METHOD_FUNC(rb_load_image), -1); - rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); - rb_define_method(rb_klass, "get_roi", RUBY_METHOD_FUNC(rb_get_roi), 0); - rb_define_alias(rb_klass, "roi", "get_roi"); - rb_define_method(rb_klass, "set_roi", RUBY_METHOD_FUNC(rb_set_roi), 1); - rb_define_alias(rb_klass, "roi=", "set_roi"); - rb_define_method(rb_klass, "reset_roi", RUBY_METHOD_FUNC(rb_reset_roi), 0); - rb_define_method(rb_klass, "get_coi", RUBY_METHOD_FUNC(rb_get_coi), 0); - rb_define_alias(rb_klass, "coi", "get_coi"); - rb_define_method(rb_klass, "set_coi", RUBY_METHOD_FUNC(rb_set_coi), 1); - rb_define_alias(rb_klass, "coi=", "set_coi"); - rb_define_method(rb_klass, "reset_coi", RUBY_METHOD_FUNC(rb_reset_coi), 0); -} - -VALUE -rb_allocate(VALUE klass) -{ - return OPENCV_OBJECT(rb_klass, 0); -} - -/* - * call-seq: - * new(width, height[, depth = CV_8U][, channel = 3]) - * - * Create width * height image. Each element-value set 0. - * - * Each element possigle range is set by depth. Default is unsigned 8bit. - * - * Number of channel is set by channel. channel should be 1..4. - * - * note: width = col, height = row, on CvMat. It is noted not to make a mistake - * because the order of arguument is differenct to CvMat. - */ -VALUE -rb_initialize(int argc, VALUE *argv, VALUE self) -{ - VALUE width, height, depth, channel; - rb_scan_args(argc, argv, "22", &width, &height, &depth, &channel); - int _depth = argc < 3 ? CV_8U : FIX2INT(depth); - int _channel = argc < 4 ? 3 : FIX2INT(channel); - DATA_PTR(self) = cvCreateImage(cvSize(FIX2INT(width), FIX2INT(height)), cvIplDepth(_depth), _channel); - return self; -} - -/* - * call-seq: - * IplImage::load(filename[,iscolor = nil]) - * - * Load an image from file. - * iscolor = true, the loaded image is forced to be color 3-channel image. - * iscolor = false, the loaded image is forced to be grayscale. - * iscolor = nil, the loaded image will be loaded as is (depend on the file). - * Currently the following file format are supported. - * * Windows bitmaps - BMP,DIB - * * JPEG files - JPEG,JPG,JPE - * * Portable Network Graphics - PNG - * * Portable image format - PBM,PGM,PPM - * * Sun rasters - SR,RAS - * * TIFF files - TIFF,TIF - */ -VALUE -rb_load_image(int argc, VALUE *argv, VALUE self) -{ - VALUE filename, iscolor; - rb_scan_args(argc, argv, "11", &filename, &iscolor); - Check_Type(filename, T_STRING); - int _iscolor; - switch (TYPE(iscolor)) { - case T_FALSE: - _iscolor = 0; - break; - case T_TRUE: - _iscolor = 1; - break; - case T_NIL: - _iscolor = -1; - break; - default: - rb_warn("argument 2 should be true(color)/false(non-color) or nil(auto)."); - _iscolor = -1; - } - IplImage *image; - if ((image = cvLoadImage(StringValueCStr(filename), _iscolor)) == NULL) { - rb_raise(rb_eStandardError, "file does not exist or invalid format image."); - } - return OPENCV_OBJECT(rb_klass, image); -} - -/* - * Get ROI as CvRect. - */ -VALUE -rb_get_roi(VALUE self) -{ - return cCvRect::new_object(cvGetImageROI(IPLIMAGE(self))); -} - -/* - * call-seq: - * set_roi(rect) - * set_roi(rect){|image| ...} - * - * Set ROI. rect should be CvRect or compatible object. - * Return self. - */ -VALUE -rb_set_roi(VALUE self, VALUE roi) -{ - VALUE block = rb_block_given_p() ? rb_block_proc() : 0; - if (block) { - CvRect prev_roi = cvGetImageROI(IPLIMAGE(self)); - cvSetImageROI(IPLIMAGE(self), VALUE_TO_CVRECT(roi)); - rb_yield_values(1, self); - cvSetImageROI(IPLIMAGE(self), prev_roi); - } else { - cvSetImageROI(IPLIMAGE(self), VALUE_TO_CVRECT(roi)); - } - return self; -} - - -/* - * Reset ROI setting. Same as IplImage#roi = nil. Return self. - */ -VALUE -rb_reset_roi(VALUE self) -{ - cvResetImageROI(IPLIMAGE(self)); - return self; -} - -/* - * Return COI as Fixnum. - */ -VALUE -rb_get_coi(VALUE self) -{ - return INT2FIX(cvGetImageCOI(IPLIMAGE(self))); -} - -/* - * call-seq: - * set_coi(coi) - * set_coi(coi){|image| ...} - * - * Set COI. coi should be Fixnum. - * Return self. - */ -VALUE -rb_set_coi(VALUE self, VALUE coi) -{ - VALUE block = rb_block_given_p() ? rb_block_proc() : 0; - if (block) { - int prev_coi = cvGetImageCOI(IPLIMAGE(self)); - cvSetImageCOI(IPLIMAGE(self), FIX2INT(coi)); - rb_yield_values(1, self); - cvSetImageCOI(IPLIMAGE(self), prev_coi); - } else { - cvSetImageCOI(IPLIMAGE(self), FIX2INT(coi)); - } - return self; -} - -/* - * Reset COI setting. Same as IplImage#coi = 0. Return self. - */ -VALUE -rb_reset_coi(VALUE self) -{ - cvSetImageCOI(IPLIMAGE(self), 0); - return self; -} - - -VALUE -new_object(int width, int height, int type) -{ - return OPENCV_OBJECT(rb_klass, cvCreateImage(cvSize(width, height), cvIplDepth(type), CV_MAT_CN(type))); -} - -VALUE -new_object(CvSize size, int type) -{ - return OPENCV_OBJECT(rb_klass, cvCreateImage(size, cvIplDepth(type), CV_MAT_CN(type))); -} - -__NAMESPACE_END_IPLIMAGE -__NAMESPACE_END_OPENCV diff --git a/ext/opencv.cpp b/ext/opencv.cpp deleted file mode 100644 index 05b1d220..00000000 --- a/ext/opencv.cpp +++ /dev/null @@ -1,481 +0,0 @@ -/************************************************************ - - opencv.cpp - - - $Author: lsxi $ - - Copyright (C) 2005-2008 Masakazu Yonekura - -************************************************************/ -/* - * Document-module: OpenCV - * - * =What is OpenCV? - * - * OpenCV is "Open Source Computer Vision Library". - * OpenCV is developed by Intel and many opensource developers. - * This library include many useful function for computer vision, such as object-detection. - * - * OpenCV is developed at - * sourceforge.net[http://sourceforge.net/projects/opencvlibrary] - * - * =What is Ruby/OpenCV? - * Ruby/OpenCV is manual Wrapper of OpenCV (not use SWIG). - * This library seem to be *Ruby*. - * * object-oriented - * * support Garbage Collection by Ruby - * Ruby/OpenCV is developed - * http://rubyforge.org/projects/opencv (Official) - * and - * http://blueruby.mydns.jp/pages/opencv (Japanese) - * - * =How to install - * - * Show INSTALL - * - * =How to generate this documentation? - * This document created by rdoc. - * If you have Ruby 1.8 or later, you might use rdoc command. - * for example - * > cd opencv - * > rdoc - * and show "./doc/index.html" - */ -#include "opencv.h" - -__NAMESPACE_BEGIN_OPENCV - - -/* - * Hashtable for protect from GC - */ -st_table *root_table = st_init_numtable(); - -/* - * Mark root object. (protect from GC) - */ -void -mark_root_object(void *ptr) -{ - VALUE value; - if(ptr && st_lookup(root_table, (st_data_t)ptr, (st_data_t*)&value)){ - rb_gc_mark(value); - } -} - -/* - * Look-up Root root object. - */ -VALUE -lookup_root_object(void *ptr) -{ - VALUE value = 0; - if(ptr) - st_lookup(root_table, (st_data_t)ptr, (st_data_t*)&value); - return value; -} - -/* - * Resist root object. - */ -void -resist_root_object(void *ptr, VALUE root) -{ - st_insert(root_table, (st_data_t)ptr, (st_data_t)root); -} - -/* - * Delete mark symbol from hashtable only, not free memory. - */ -void -unresist_object(void *ptr) -{ - st_delete(root_table, (st_data_t*)&ptr, 0); -} - -/* - * Delete mark symbol from hash table, then free memory. - */ -void -free_object(void *ptr) -{ - if(ptr){ - unresist_object(ptr); - cvFree(&ptr); - } -} - -/* - * Release OpenCV specific structure(i.e CvMat, IplImage..) from memory and delete from hashtable. - */ -void -release_object(void *ptr) -{ - if(ptr){ - unresist_object(ptr); - cvRelease(&ptr); - } -} - -VALUE rb_module; -VALUE rb_opencv_constants; - -VALUE -rb_module_opencv() -{ - return rb_module; -} - -/* - * convert OpenCV internal error to Ruby exception. - */ -int -error_callback(int status, - const char *function_name, - const char *error_message, - const char *file_name, - int line, - void *user_data) -{ - int error_code = (CvStatus)cvGetErrStatus(); - if(error_code){ - OPENCV_RSTERR(); // = CV_StsOk - rb_warn("OpenCV error code (%d) : %s (%d in %s)", error_code, function_name, line, file_name); - rb_raise(mCvError::by_code(error_code), "%s", error_message); - } - return 0; -} - -void -define_ruby_module() -{ - if(rb_module) - return; - rb_module = rb_define_module("OpenCV"); - - /* 0: 8bit unsigned */ - rb_define_const(rb_module, "CV_8U", INT2FIX(CV_8U)); - /* 1: 8bit signed */ - rb_define_const(rb_module, "CV_8S", INT2FIX(CV_8S)); - /* 2: 16bit unsigned */ - rb_define_const(rb_module, "CV_16U", INT2FIX(CV_16U)); - /* 3: 16bit signed */ - rb_define_const(rb_module, "CV_16S", INT2FIX(CV_16S)); - /* 4: 32bit signed */ - rb_define_const(rb_module, "CV_32S", INT2FIX(CV_32S)); - /* 5: 32bit floating-point */ - rb_define_const(rb_module, "CV_32F", INT2FIX(CV_32F)); - /* 6: 64bit floating-point */ - rb_define_const(rb_module, "CV_64F", INT2FIX(CV_64F)); - - - VALUE inversion_method = rb_hash_new(); - /* {:lu, :svd, :svd_sym(:svd_symmetric)}: Inversion method */ - rb_define_const(rb_module, "INVERSION_METHOD", inversion_method); - RESIST_CVMETHOD(inversion_method, "lu", CV_LU); - RESIST_CVMETHOD(inversion_method, "svd", CV_SVD); - RESIST_CVMETHOD(inversion_method, "svd_sym", CV_SVD_SYM); - RESIST_CVMETHOD(inversion_method, "svd_symmetric", CV_SVD_SYM); - - VALUE dxt_flag = rb_hash_new(); - /* {:forward, :inverse, :scale, :rows}: DFT and DCT flags */ - rb_define_const(rb_module, "DXT_FLAG", dxt_flag); - RESIST_CVMETHOD(dxt_flag, "forward", CV_DXT_FORWARD); - RESIST_CVMETHOD(dxt_flag, "inverse", CV_DXT_INVERSE); - RESIST_CVMETHOD(dxt_flag, "scale", CV_DXT_SCALE); - RESIST_CVMETHOD(dxt_flag, "rows", CV_DXT_ROWS); - - VALUE interpolation_method = rb_hash_new(); - /* {:nn, :linear, :area, :cubic}: Interpolation method */ - rb_define_const(rb_module, "INTERPOLATION_METHOD", interpolation_method); - RESIST_CVMETHOD(interpolation_method, "nn", CV_INTER_NN); - RESIST_CVMETHOD(interpolation_method, "linear", CV_INTER_LINEAR); - RESIST_CVMETHOD(interpolation_method, "area", CV_INTER_AREA); - RESIST_CVMETHOD(interpolation_method, "cubic", CV_INTER_CUBIC); - - VALUE warp_flag = rb_hash_new(); - /* {:fill_outliers, :inverse_map}: Warp affine optional flags */ - rb_define_const(rb_module, "WARP_FLAG", warp_flag); - RESIST_CVMETHOD(warp_flag, "fill_outliers", CV_WARP_FILL_OUTLIERS); - RESIST_CVMETHOD(warp_flag, "inverse_map", CV_WARP_INVERSE_MAP); - - VALUE depth = rb_hash_new(); - /* {:cv8u, :cv8s, :cv16u, :cv16s, :cv32s, :cv32f, :cv64f}: Depth of each pixel. */ - rb_define_const(rb_module, "DEPTH", depth); - RESIST_CVMETHOD(depth, "cv8u", CV_8U); - RESIST_CVMETHOD(depth, "cv8s", CV_8S); - RESIST_CVMETHOD(depth, "cv16u", CV_16U); - RESIST_CVMETHOD(depth, "cv16s", CV_16S); - RESIST_CVMETHOD(depth, "cv32s", CV_32S); - RESIST_CVMETHOD(depth, "cv32f", CV_32F); - RESIST_CVMETHOD(depth, "cv64f", CV_64F); - - VALUE connectivity = rb_hash_new(); - /* {:aa(:anti_alias)}: Determined by the closeness of pixel values */ - rb_define_const(rb_module, "CONNECTIVITY", connectivity); - RESIST_CVMETHOD(depth, "aa", CV_AA); - RESIST_CVMETHOD(depth, "anti_alias", CV_AA); - - VALUE retrieval_mode = rb_hash_new(); - /* {:external, :list, :ccomp, :tree}: Retrieval mode */ - rb_define_const(rb_module, "RETRIEVAL_MODE", retrieval_mode); - RESIST_CVMETHOD(retrieval_mode, "external", CV_RETR_EXTERNAL); - RESIST_CVMETHOD(retrieval_mode, "list", CV_RETR_LIST); - RESIST_CVMETHOD(retrieval_mode, "ccomp", CV_RETR_CCOMP); - RESIST_CVMETHOD(retrieval_mode, "tree", CV_RETR_TREE); - - VALUE approx_chain_method = rb_hash_new(); - /* {:code, :approx_none, :approx_simple, :apporx_tc89_11, :approx_tc89_kcos}: Approximation method */ - rb_define_const(rb_module, "APPROX_CHAIN_METHOD", approx_chain_method); - RESIST_CVMETHOD(approx_chain_method, "code", CV_CHAIN_CODE); - RESIST_CVMETHOD(approx_chain_method, "approx_none", CV_CHAIN_APPROX_NONE); - RESIST_CVMETHOD(approx_chain_method, "approx_simple", CV_CHAIN_APPROX_SIMPLE); - RESIST_CVMETHOD(approx_chain_method, "approx_tc89_l1", CV_CHAIN_APPROX_TC89_L1); - RESIST_CVMETHOD(approx_chain_method, "approx_tc89_kcos", CV_CHAIN_APPROX_TC89_KCOS); - - VALUE approx_poly_method = rb_hash_new(); - /* {:dp}: Approximation method (polygon) */ - rb_define_const(rb_module, "APPROX_POLY_METHOD", approx_poly_method); - RESIST_CVMETHOD(approx_poly_method, "dp", CV_POLY_APPROX_DP); - - VALUE match_template_method = rb_hash_new(); - /* {:sqdiff, :sqdiff_normed, :ccorr, :ccorr_normed, :ccoeff, :ccoeff_normed}: Match template method */ - rb_define_const(rb_module, "MATCH_TEMPLATE_METHOD", match_template_method); - RESIST_CVMETHOD(match_template_method, "sqdiff", CV_TM_SQDIFF); - RESIST_CVMETHOD(match_template_method, "sqdiff_normed", CV_TM_SQDIFF_NORMED); - RESIST_CVMETHOD(match_template_method, "ccorr", CV_TM_CCORR); - RESIST_CVMETHOD(match_template_method, "ccorr_normed", CV_TM_CCORR_NORMED); - RESIST_CVMETHOD(match_template_method, "ccoeff", CV_TM_CCOEFF); - RESIST_CVMETHOD(match_template_method, "ccoeff_normed", CV_TM_CCOEFF_NORMED); - - /* color convert methods */ - rb_define_module_function(rb_module, "BGR2BGRA", RUBY_METHOD_FUNC(rb_BGR2BGRA), 1); - rb_define_module_function(rb_module, "RGB2RGBA", RUBY_METHOD_FUNC(rb_RGB2RGBA), 1); - rb_define_module_function(rb_module, "BGRA2BGR", RUBY_METHOD_FUNC(rb_BGRA2BGR), 1); - rb_define_module_function(rb_module, "RGBA2RGB", RUBY_METHOD_FUNC(rb_RGBA2RGB), 1); - rb_define_module_function(rb_module, "BGR2RGBA", RUBY_METHOD_FUNC(rb_BGR2RGBA), 1); - rb_define_module_function(rb_module, "RGB2BGRA", RUBY_METHOD_FUNC(rb_RGB2BGRA), 1); - rb_define_module_function(rb_module, "RGBA2BGR", RUBY_METHOD_FUNC(rb_RGBA2BGR), 1); - rb_define_module_function(rb_module, "BGRA2RGB", RUBY_METHOD_FUNC(rb_BGRA2RGB), 1); - rb_define_module_function(rb_module, "BGR2RGB", RUBY_METHOD_FUNC(rb_BGR2RGB), 1); - rb_define_module_function(rb_module, "RGB2BGR", RUBY_METHOD_FUNC(rb_RGB2BGR), 1); - rb_define_module_function(rb_module, "BGRA2RGBA", RUBY_METHOD_FUNC(rb_BGRA2RGBA), 1); - rb_define_module_function(rb_module, "RGBA2BGRA", RUBY_METHOD_FUNC(rb_RGBA2BGRA), 1); - rb_define_module_function(rb_module, "BGR2GRAY", RUBY_METHOD_FUNC(rb_BGR2GRAY), 1); - rb_define_module_function(rb_module, "RGB2GRAY", RUBY_METHOD_FUNC(rb_RGB2GRAY), 1); - rb_define_module_function(rb_module, "GRAY2BGR", RUBY_METHOD_FUNC(rb_GRAY2BGR), 1); - rb_define_module_function(rb_module, "GRAY2RGB", RUBY_METHOD_FUNC(rb_GRAY2RGB), 1); - rb_define_module_function(rb_module, "GRAY2BGRA", RUBY_METHOD_FUNC(rb_GRAY2BGRA), 1); - rb_define_module_function(rb_module, "GRAY2RGBA", RUBY_METHOD_FUNC(rb_GRAY2RGBA), 1); - rb_define_module_function(rb_module, "BGRA2GRAY", RUBY_METHOD_FUNC(rb_BGRA2GRAY), 1); - rb_define_module_function(rb_module, "RGBA2GRAY", RUBY_METHOD_FUNC(rb_RGBA2GRAY), 1); - rb_define_module_function(rb_module, "BGR2BGR565", RUBY_METHOD_FUNC(rb_BGR2BGR565), 1); - rb_define_module_function(rb_module, "RGB2BGR565", RUBY_METHOD_FUNC(rb_RGB2BGR565), 1); - rb_define_module_function(rb_module, "BGR5652BGR", RUBY_METHOD_FUNC(rb_BGR5652BGR), 1); - rb_define_module_function(rb_module, "BGR5652RGB", RUBY_METHOD_FUNC(rb_BGR5652RGB), 1); - rb_define_module_function(rb_module, "BGRA2BGR565", RUBY_METHOD_FUNC(rb_BGRA2BGR565), 1); - rb_define_module_function(rb_module, "RGBA2BGR565", RUBY_METHOD_FUNC(rb_RGBA2BGR565), 1); - rb_define_module_function(rb_module, "BGR5652BGRA", RUBY_METHOD_FUNC(rb_BGR5652BGRA), 1); - rb_define_module_function(rb_module, "BGR5652RGBA", RUBY_METHOD_FUNC(rb_BGR5652RGBA), 1); - rb_define_module_function(rb_module, "GRAY2BGR565", RUBY_METHOD_FUNC(rb_GRAY2BGR565), 1); - rb_define_module_function(rb_module, "BGR5652GRAY", RUBY_METHOD_FUNC(rb_BGR5652GRAY), 1); - rb_define_module_function(rb_module, "BGR2BGR555", RUBY_METHOD_FUNC(rb_BGR2BGR555), 1); - rb_define_module_function(rb_module, "RGB2BGR555", RUBY_METHOD_FUNC(rb_RGB2BGR555), 1); - rb_define_module_function(rb_module, "BGR5552BGR", RUBY_METHOD_FUNC(rb_BGR5552BGR), 1); - rb_define_module_function(rb_module, "BGR5552RGB", RUBY_METHOD_FUNC(rb_BGR5552RGB), 1); - rb_define_module_function(rb_module, "BGRA2BGR555", RUBY_METHOD_FUNC(rb_BGRA2BGR555), 1); - rb_define_module_function(rb_module, "RGBA2BGR555", RUBY_METHOD_FUNC(rb_RGBA2BGR555), 1); - rb_define_module_function(rb_module, "BGR5552BGRA", RUBY_METHOD_FUNC(rb_BGR5552BGRA), 1); - rb_define_module_function(rb_module, "BGR5552RGBA", RUBY_METHOD_FUNC(rb_BGR5552RGBA), 1); - rb_define_module_function(rb_module, "GRAY2BGR555", RUBY_METHOD_FUNC(rb_GRAY2BGR555), 1); - rb_define_module_function(rb_module, "BGR5552GRAY", RUBY_METHOD_FUNC(rb_BGR5552GRAY), 1); - rb_define_module_function(rb_module, "BGR2XYZ", RUBY_METHOD_FUNC(rb_BGR2XYZ), 1); - rb_define_module_function(rb_module, "RGB2XYZ", RUBY_METHOD_FUNC(rb_RGB2XYZ), 1); - rb_define_module_function(rb_module, "XYZ2BGR", RUBY_METHOD_FUNC(rb_XYZ2BGR), 1); - rb_define_module_function(rb_module, "XYZ2RGB", RUBY_METHOD_FUNC(rb_XYZ2RGB), 1); - rb_define_module_function(rb_module, "BGR2YCrCb", RUBY_METHOD_FUNC(rb_BGR2YCrCb), 1); - rb_define_module_function(rb_module, "RGB2YCrCb", RUBY_METHOD_FUNC(rb_RGB2YCrCb), 1); - rb_define_module_function(rb_module, "YCrCb2BGR", RUBY_METHOD_FUNC(rb_YCrCb2BGR), 1); - rb_define_module_function(rb_module, "YCrCb2RGB", RUBY_METHOD_FUNC(rb_YCrCb2RGB), 1); - rb_define_module_function(rb_module, "BGR2HSV", RUBY_METHOD_FUNC(rb_BGR2HSV), 1); - rb_define_module_function(rb_module, "RGB2HSV", RUBY_METHOD_FUNC(rb_RGB2HSV), 1); - rb_define_module_function(rb_module, "BGR2Lab", RUBY_METHOD_FUNC(rb_BGR2Lab), 1); - rb_define_module_function(rb_module, "RGB2Lab", RUBY_METHOD_FUNC(rb_RGB2Lab), 1); - rb_define_module_function(rb_module, "BayerBG2BGR", RUBY_METHOD_FUNC(rb_BayerBG2BGR), 1); - rb_define_module_function(rb_module, "BayerGB2BGR", RUBY_METHOD_FUNC(rb_BayerGB2BGR), 1); - rb_define_module_function(rb_module, "BayerRG2BGR", RUBY_METHOD_FUNC(rb_BayerRG2BGR), 1); - rb_define_module_function(rb_module, "BayerGR2BGR", RUBY_METHOD_FUNC(rb_BayerGR2BGR), 1); - rb_define_module_function(rb_module, "BayerBG2RGB", RUBY_METHOD_FUNC(rb_BayerBG2RGB), 1); - rb_define_module_function(rb_module, "BayerGB2RGB", RUBY_METHOD_FUNC(rb_BayerGB2RGB), 1); - rb_define_module_function(rb_module, "BayerRG2RGB", RUBY_METHOD_FUNC(rb_BayerRG2RGB), 1); - rb_define_module_function(rb_module, "BayerGR2RGB", RUBY_METHOD_FUNC(rb_BayerGR2RGB), 1); - rb_define_module_function(rb_module, "BGR2Luv", RUBY_METHOD_FUNC(rb_BGR2Luv), 1); - rb_define_module_function(rb_module, "RGB2Luv", RUBY_METHOD_FUNC(rb_RGB2Luv), 1); - rb_define_module_function(rb_module, "BGR2HLS", RUBY_METHOD_FUNC(rb_BGR2HLS), 1); - rb_define_module_function(rb_module, "RGB2HLS", RUBY_METHOD_FUNC(rb_RGB2HLS), 1); - rb_define_module_function(rb_module, "HSV2BGR", RUBY_METHOD_FUNC(rb_HSV2BGR), 1); - rb_define_module_function(rb_module, "HSV2RGB", RUBY_METHOD_FUNC(rb_HSV2RGB), 1); - rb_define_module_function(rb_module, "Lab2BGR", RUBY_METHOD_FUNC(rb_Lab2BGR), 1); - rb_define_module_function(rb_module, "Lab2RGB", RUBY_METHOD_FUNC(rb_Lab2RGB), 1); - rb_define_module_function(rb_module, "Luv2BGR", RUBY_METHOD_FUNC(rb_Luv2BGR), 1); - rb_define_module_function(rb_module, "Luv2RGB", RUBY_METHOD_FUNC(rb_Luv2RGB), 1); - rb_define_module_function(rb_module, "HLS2BGR", RUBY_METHOD_FUNC(rb_HLS2BGR), 1); - rb_define_module_function(rb_module, "HLS2RGB", RUBY_METHOD_FUNC(rb_HLS2RGB), 1); -} - -#define CREATE_CVTCOLOR_FUNC(rb_func_name, c_const_name, src_cn, dest_cn) \ - VALUE rb_func_name(VALUE klass, VALUE image) \ - { \ - VALUE dest; \ - if (!rb_obj_is_kind_of(image, cCvMat::rb_class())) \ - rb_raise(rb_eTypeError, "argument 1 should be %s.", rb_class2name(cCvMat::rb_class())); \ - int type = cvGetElemType(CVARR(image)); \ - if (CV_MAT_CN(type) != src_cn) \ - rb_raise(rb_eTypeError, "argument 1 should be %d-channel.", src_cn); \ - dest = cIplImage::new_object(cvGetSize(CVARR(image)), CV_MAKETYPE(CV_MAT_DEPTH(type), dest_cn)); \ - cvCvtColor(CVARR(image), CVARR(dest), c_const_name); \ - return dest; \ - } - -CREATE_CVTCOLOR_FUNC(rb_BGR2BGRA, CV_BGR2BGRA, 3, 4); -CREATE_CVTCOLOR_FUNC(rb_RGB2RGBA, CV_RGB2RGBA, 3, 4); -CREATE_CVTCOLOR_FUNC(rb_BGRA2BGR, CV_BGRA2BGR, 4, 3); -CREATE_CVTCOLOR_FUNC(rb_RGBA2RGB, CV_RGBA2RGB, 4, 3); -CREATE_CVTCOLOR_FUNC(rb_BGR2RGBA, CV_BGR2RGBA, 3, 4); -CREATE_CVTCOLOR_FUNC(rb_RGB2BGRA, CV_RGB2BGRA, 3, 4); -CREATE_CVTCOLOR_FUNC(rb_RGBA2BGR, CV_RGBA2BGR, 4, 3); -CREATE_CVTCOLOR_FUNC(rb_BGRA2RGB, CV_BGRA2RGB, 4, 3); -CREATE_CVTCOLOR_FUNC(rb_BGR2RGB, CV_BGR2RGB, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_RGB2BGR, CV_RGB2BGR, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_BGRA2RGBA, CV_BGRA2RGBA, 4, 4); -CREATE_CVTCOLOR_FUNC(rb_RGBA2BGRA, CV_RGBA2BGRA, 4, 4); -CREATE_CVTCOLOR_FUNC(rb_BGR2GRAY, CV_BGR2GRAY, 3, 1); -CREATE_CVTCOLOR_FUNC(rb_RGB2GRAY, CV_RGB2GRAY, 3, 1); -CREATE_CVTCOLOR_FUNC(rb_GRAY2BGR, CV_GRAY2BGR, 1, 3); -CREATE_CVTCOLOR_FUNC(rb_GRAY2RGB, CV_GRAY2RGB, 1, 3); -CREATE_CVTCOLOR_FUNC(rb_GRAY2BGRA, CV_GRAY2BGRA, 1, 4); -CREATE_CVTCOLOR_FUNC(rb_GRAY2RGBA, CV_GRAY2RGBA, 1, 4); -CREATE_CVTCOLOR_FUNC(rb_BGRA2GRAY, CV_BGRA2GRAY, 4, 1); -CREATE_CVTCOLOR_FUNC(rb_RGBA2GRAY, CV_RGBA2GRAY, 4, 1); -CREATE_CVTCOLOR_FUNC(rb_BGR2BGR565, CV_BGR2BGR565, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_RGB2BGR565, CV_RGB2BGR565, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_BGR5652BGR, CV_BGR5652BGR, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_BGR5652RGB, CV_BGR5652RGB, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_BGRA2BGR565, CV_BGRA2BGR565, 4, 3); -CREATE_CVTCOLOR_FUNC(rb_RGBA2BGR565, CV_RGBA2BGR565, 4, 3); -CREATE_CVTCOLOR_FUNC(rb_BGR5652BGRA, CV_BGR5652BGRA, 3, 4); -CREATE_CVTCOLOR_FUNC(rb_BGR5652RGBA, CV_BGR5652RGBA, 3, 4); -CREATE_CVTCOLOR_FUNC(rb_GRAY2BGR565, CV_GRAY2BGR565, 1, 3); -CREATE_CVTCOLOR_FUNC(rb_BGR5652GRAY, CV_BGR5652GRAY, 3, 1); -CREATE_CVTCOLOR_FUNC(rb_BGR2BGR555, CV_BGR2BGR555, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_RGB2BGR555, CV_RGB2BGR555, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_BGR5552BGR, CV_BGR5552BGR, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_BGR5552RGB, CV_BGR5552RGB, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_BGRA2BGR555, CV_BGRA2BGR555, 4, 3); -CREATE_CVTCOLOR_FUNC(rb_RGBA2BGR555, CV_RGBA2BGR555, 4, 3); -CREATE_CVTCOLOR_FUNC(rb_BGR5552BGRA, CV_BGR5552BGRA, 3, 4); -CREATE_CVTCOLOR_FUNC(rb_BGR5552RGBA, CV_BGR5552RGBA, 3, 4); -CREATE_CVTCOLOR_FUNC(rb_GRAY2BGR555, CV_GRAY2BGR555, 1, 3); -CREATE_CVTCOLOR_FUNC(rb_BGR5552GRAY, CV_BGR5552GRAY, 3, 1); -CREATE_CVTCOLOR_FUNC(rb_BGR2XYZ, CV_BGR2XYZ, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_RGB2XYZ, CV_RGB2XYZ, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_XYZ2BGR, CV_XYZ2BGR, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_XYZ2RGB, CV_XYZ2RGB, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_BGR2YCrCb, CV_BGR2YCrCb, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_RGB2YCrCb, CV_RGB2YCrCb, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_YCrCb2BGR, CV_YCrCb2BGR, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_YCrCb2RGB, CV_YCrCb2RGB, 0, 3); -CREATE_CVTCOLOR_FUNC(rb_BGR2HSV, CV_BGR2HSV, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_RGB2HSV, CV_RGB2HSV, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_BGR2Lab, CV_BGR2Lab, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_RGB2Lab, CV_RGB2Lab, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_BayerBG2BGR, CV_BayerBG2BGR, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_BayerGB2BGR, CV_BayerGB2BGR, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_BayerRG2BGR, CV_BayerRG2BGR, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_BayerGR2BGR, CV_BayerGR2BGR, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_BayerBG2RGB, CV_BayerBG2RGB, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_BayerGB2RGB, CV_BayerGB2RGB, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_BayerRG2RGB, CV_BayerRG2RGB, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_BayerGR2RGB, CV_BayerGR2RGB, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_BGR2Luv, CV_BGR2Luv, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_RGB2Luv, CV_RGB2Luv, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_BGR2HLS, CV_BGR2HLS, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_RGB2HLS, CV_RGB2HLS, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_HSV2BGR, CV_HSV2BGR, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_HSV2RGB, CV_HSV2RGB, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_Lab2BGR, CV_Lab2BGR, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_Lab2RGB, CV_Lab2RGB, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_Luv2BGR, CV_Luv2BGR, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_Luv2RGB, CV_Luv2RGB, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_HLS2BGR, CV_HLS2BGR, 3, 3); -CREATE_CVTCOLOR_FUNC(rb_HLS2RGB, CV_HLS2RGB, 3, 3); - -__NAMESPACE_END_OPENCV - -extern "C"{ - void - Init_opencv() - { - cvRedirectError((CvErrorCallback)mOpenCV::error_callback); - - mOpenCV::define_ruby_module(); - - mOpenCV::mCvError::define_ruby_module(); - mOpenCV::cCvPoint::define_ruby_class(); - mOpenCV::cCvPoint2D32f::define_ruby_class(); - mOpenCV::cCvPoint3D32f::define_ruby_class(); - mOpenCV::cCvSize::define_ruby_class(); - mOpenCV::cCvSize2D32f::define_ruby_class(); - mOpenCV::cCvRect::define_ruby_class(); - mOpenCV::cCvScalar::define_ruby_class(); - mOpenCV::cCvSlice::define_ruby_class(); - mOpenCV::cCvTermCriteria::define_ruby_class(); - mOpenCV::cCvBox2D::define_ruby_class(); - mOpenCV::cCvFont::define_ruby_class(); - mOpenCV::cIplConvKernel::define_ruby_class(); - mOpenCV::cCvMoments::define_ruby_class(); - mOpenCV::cCvConvexityDefect::define_ruby_class(); - - mOpenCV::cCvMemStorage::define_ruby_class(); - - mOpenCV::cCvSeq::define_ruby_class(); - mOpenCV::mCurve::define_ruby_module(); - mOpenCV::mPointSet::define_ruby_module(); - mOpenCV::mPoint3DSet::define_ruby_module(); - mOpenCV::cCvSet::define_ruby_class(); - mOpenCV::cCvChain::define_ruby_class(); - mOpenCV::cCvChainCode::define_ruby_class(); - mOpenCV::cCvContour::define_ruby_class(); - mOpenCV::cCvContourTree::define_ruby_class(); - - mOpenCV::cCvMat::define_ruby_class(); - mOpenCV::cIplImage::define_ruby_class(); - mOpenCV::cCvMatND::define_ruby_class(); - mOpenCV::cCvSparseMat::define_ruby_class(); - mOpenCV::cCvHistogram::define_ruby_class(); - mOpenCV::cCvCapture::define_ruby_class(); - - mOpenCV::cCvIndex::define_ruby_class(); - mOpenCV::cCvLine::define_ruby_class(); - mOpenCV::cCvTwoPoints::define_ruby_class(); - mOpenCV::cCvCircle32f::define_ruby_class(); - - mOpenCV::cCvConDensation::define_ruby_class(); - - mOpenCV::cCvConnectedComp::define_ruby_class(); - mOpenCV::cCvAvgComp::define_ruby_class(); - mOpenCV::cCvHaarClassifierCascade::define_ruby_class(); -#ifdef HAVE_CALLBACK_H - mOpenCV::mGUI::define_ruby_module(); - mOpenCV::mGUI::cWindow::define_ruby_class(); - mOpenCV::mGUI::cTrackbar::define_ruby_class(); - mOpenCV::mGUI::cMouseEvent::define_ruby_class(); -#endif - -#ifdef HAVE_ML_H - /* feature support. - mOpenCV::mMachineLearning::define_ruby_module(); - */ -#endif - } -} diff --git a/ext/opencv/algorithm.cpp b/ext/opencv/algorithm.cpp new file mode 100644 index 00000000..d702b428 --- /dev/null +++ b/ext/opencv/algorithm.cpp @@ -0,0 +1,291 @@ +/************************************************************ + + algorithm.cpp - + + $Author: ser1zw $ + + Copyright (C) 2013 ser1zw + +************************************************************/ +#include +#include "algorithm.h" +/* + * Document-class: OpenCV::Algorithm + * + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_ALGORITHM + +VALUE rb_klass; + +VALUE +rb_class() +{ + return rb_klass; +} + +VALUE +rb_set_int(VALUE self, VALUE parameter, VALUE value) +{ + Check_Type(parameter, T_STRING); + try { + ALGORITHM(self)->setInt(StringValueCStr(parameter), NUM2INT(value)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return Qnil; +} + +VALUE +rb_set_double(VALUE self, VALUE parameter, VALUE value) +{ + Check_Type(parameter, T_STRING); + try { + ALGORITHM(self)->setDouble(StringValueCStr(parameter), NUM2DBL(value)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return Qnil; +} + +VALUE +rb_set_bool(VALUE self, VALUE parameter, VALUE value) +{ + Check_Type(parameter, T_STRING); + try { + bool val = TRUE_OR_FALSE(value) ? true : false; + ALGORITHM(self)->setBool(StringValueCStr(parameter), val); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return Qnil; +} + +VALUE +rb_set_string(VALUE self, VALUE parameter, VALUE value) +{ + Check_Type(parameter, T_STRING); + Check_Type(value, T_STRING); + try { + ALGORITHM(self)->setString(StringValueCStr(parameter), StringValueCStr(value)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return Qnil; +} + +VALUE +rb_set_mat(VALUE self, VALUE parameter, VALUE value) +{ + Check_Type(parameter, T_STRING); + try { + CvMat* val = CVMAT_WITH_CHECK(value); + cv::Mat mat(val); + ALGORITHM(self)->setMat(StringValueCStr(parameter), mat); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return Qnil; +} + +VALUE +rb_set_matvector(VALUE self, VALUE parameter, VALUE value) +{ + Check_Type(parameter, T_STRING); + Check_Type(value, T_ARRAY); + try { + long len = RARRAY_LEN(value); + VALUE* value_ptr = RARRAY_PTR(value); + std::vector mat_vector; + for (int i = 0; i < len; i++) { + CvMat* val = CVMAT_WITH_CHECK(value_ptr[i]); + cv::Mat mat(val); + mat_vector.push_back(mat); + } + ALGORITHM(self)->setMatVector(StringValueCStr(parameter), mat_vector); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return Qnil; +} + +VALUE +rb_set_algorithm(VALUE self, VALUE parameter, VALUE value) +{ + Check_Type(parameter, T_STRING); + try { + ALGORITHM(self)->setAlgorithm(StringValueCStr(parameter), ALGORITHM(value)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return Qnil; +} + + +VALUE +rb_get_int(VALUE self, VALUE parameter) +{ + Check_Type(parameter, T_STRING); + int value = 0; + try { + value = ALGORITHM(self)->getInt(StringValueCStr(parameter)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return INT2NUM(value); +} + +VALUE +rb_get_double(VALUE self, VALUE parameter) +{ + Check_Type(parameter, T_STRING); + double value = 0.0; + try { + value = ALGORITHM(self)->getDouble(StringValueCStr(parameter)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return DBL2NUM(value); +} + +VALUE +rb_get_bool(VALUE self, VALUE parameter) +{ + Check_Type(parameter, T_STRING); + bool value = false; + try { + value = ALGORITHM(self)->getBool(StringValueCStr(parameter)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return value ? Qtrue : Qfalse; +} + +VALUE +rb_get_string(VALUE self, VALUE parameter) +{ + Check_Type(parameter, T_STRING); + std::string value = ""; + try { + value = ALGORITHM(self)->getString(StringValueCStr(parameter)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return rb_str_new_cstr(value.c_str()); +} + +VALUE +rb_get_mat(VALUE self, VALUE parameter) +{ + Check_Type(parameter, T_STRING); + VALUE mat = Qnil; + try { + cv::Mat value = ALGORITHM(self)->getMat(StringValueCStr(parameter)); + cv::Size size = value.size(); + mat = cCvMat::new_object(size.height, size.width, value.type()); + cv::Mat dst(CVMAT(mat)); + value.copyTo(dst); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return mat; +} + +VALUE +rb_get_matvector(VALUE self, VALUE parameter) +{ + Check_Type(parameter, T_STRING); + VALUE array = Qnil; + try { + std::vector value = ALGORITHM(self)->getMatVector(StringValueCStr(parameter)); + int len = value.size(); + array = rb_ary_new2(len); + for (int i = 0; i < len; i++) { + cv::Mat m = value[i]; + cv::Size size = m.size(); + VALUE mat = cCvMat::new_object(size.height, size.width, m.type()); + cv::Mat dst(CVMAT(mat)); + m.copyTo(dst); + rb_ary_store(array, i, mat); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return array; +} + +VALUE +rb_name(VALUE self) +{ + VALUE name = Qnil; + try { + name = rb_str_new_cstr(ALGORITHM(self)->name().c_str()); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return name; +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + rb_klass = rb_define_class_under(opencv, "Algorithm", rb_cObject); + rb_define_method(rb_klass, "set_int", RUBY_METHOD_FUNC(rb_set_int), 2); + rb_define_method(rb_klass, "set_double", RUBY_METHOD_FUNC(rb_set_double), 2); + rb_define_method(rb_klass, "set_bool", RUBY_METHOD_FUNC(rb_set_bool), 2); + rb_define_method(rb_klass, "set_string", RUBY_METHOD_FUNC(rb_set_string), 2); + rb_define_method(rb_klass, "set_mat", RUBY_METHOD_FUNC(rb_set_mat), 2); + rb_define_method(rb_klass, "set_matvector", RUBY_METHOD_FUNC(rb_set_matvector), 2); + rb_define_method(rb_klass, "set_algorithm", RUBY_METHOD_FUNC(rb_set_algorithm), 2); + + rb_define_method(rb_klass, "get_int", RUBY_METHOD_FUNC(rb_get_int), 1); + rb_define_method(rb_klass, "get_double", RUBY_METHOD_FUNC(rb_get_double), 1); + rb_define_method(rb_klass, "get_bool", RUBY_METHOD_FUNC(rb_get_bool), 1); + rb_define_method(rb_klass, "get_string", RUBY_METHOD_FUNC(rb_get_string), 1); + rb_define_method(rb_klass, "get_mat", RUBY_METHOD_FUNC(rb_get_mat), 1); + rb_define_method(rb_klass, "get_matvector", RUBY_METHOD_FUNC(rb_get_matvector), 1); + + rb_define_method(rb_klass, "name", RUBY_METHOD_FUNC(rb_name), 0); +} + +__NAMESPACE_END_ALGORITM +__NAMESPACE_END_OPENCV + diff --git a/ext/opencv/algorithm.h b/ext/opencv/algorithm.h new file mode 100644 index 00000000..945ee69f --- /dev/null +++ b/ext/opencv/algorithm.h @@ -0,0 +1,38 @@ +/************************************************************ + + algorithm.h + + $Author: ser1zw $ + + Copyright (C) 2013 ser1zw + +************************************************************/ +#ifndef RUBY_OPENCV_ALGORITHM_H +#define RUBY_OPENCV_ALGORITHM_H + +#include "opencv.h" + +#define __NAMESPACE_BEGIN_ALGORITHM namespace cAlgorithm { +#define __NAMESPACE_END_ALGORITM } + +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_ALGORITHM + +VALUE rb_class(); + +void init_ruby_class(); + +__NAMESPACE_END_ALGORITM + +inline cv::Algorithm* +ALGORITHM(VALUE object) +{ + cv::Algorithm *ptr; + Data_Get_Struct(object, cv::Algorithm, ptr); + return ptr; +} + +__NAMESPACE_END_OPENCV + +#endif // RUBY_OPENCV_ALGORITHM_H + diff --git a/ext/opencv/curve.cpp b/ext/opencv/curve.cpp new file mode 100644 index 00000000..1aa0c823 --- /dev/null +++ b/ext/opencv/curve.cpp @@ -0,0 +1,127 @@ +/************************************************************ + + curve.cpp - + + $Author: lsxi $ + + Copyright (C) 2005 Masakazu Yonekura + +************************************************************/ +#include "curve.h" +/* + * Document-class: OpenCV::Curve + * + * Curve sequence + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CURVE + +VALUE module; + +VALUE +rb_module() +{ + return module; +} + +/* + * If the curve is closed, return true. Otherwise return false. + * @overload closed? + * @return [Boolean] Closed or not + * @opencv_func CV_IS_SEQ_CLOSED + */ +VALUE +rb_closed_q(VALUE self) +{ + return CV_IS_SEQ_CLOSED(CVSEQ(self)) ? Qtrue : Qfalse; +} + +/* + * If the curve is convex, return true. Otherwise return false. + * @overload convex? + * @return [Boolean] Convex or not + * @opencv_func CV_IS_SEQ_CONVEX + */ +VALUE +rb_convex_q(VALUE self) +{ + return CV_IS_SEQ_CONVEX(CVSEQ(self)) ? Qtrue : Qfalse; +} + +/* + * If the curve is hole(inner contour), return true. Otherwise return false. + * @overload hole? + * @return [Boolean] Hole or not + * @opencv_func CV_IS_SEQ_HOLE + */ +VALUE +rb_hole_q(VALUE self) +{ + return CV_IS_SEQ_HOLE(CVSEQ(self)) ? Qtrue : Qfalse; +} + +/* + * If the curve is simple, return true. Otherwise return false. + * @overload simple? + * @return [Boolean] Simple or not + * @opencv_func CV_IS_SEQ_SIMPLE + */ +VALUE +rb_simple_q(VALUE self) +{ + return CV_IS_SEQ_SIMPLE(CVSEQ(self)) ? Qtrue : Qfalse; +} + +/* + * Calculates length of a curve + * @overload arc_length(slice = nil, is_closed = nil) + * @param slice [Range,CvSlice,nil] Starting and ending points of the curve. + * By default, the whole curve length is calculated. + * @param is_closed [Boolean,nil] Indicates whether the curve is closed or not. + * There are 3 cases: + * * is_closed = true - the curve is assumed to be unclosed. + * * is_closed = false - the curve is assumed to be closed. + * * is_closed = nil (default) use self#closed? + * @return [Number] Length of the curve + * @opencv_func cvArcLength + */ +VALUE +rb_arc_length(int argc, VALUE *argv, VALUE self) +{ + VALUE slice, is_closed; + rb_scan_args(argc, argv, "02", &slice, &is_closed); + double length = 0; + try { + length = cvArcLength(CVARR(self), + NIL_P(slice) ? CV_WHOLE_SEQ : VALUE_TO_CVSLICE(slice), + TRUE_OR_FALSE(is_closed, -1)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_float_new(length); +} + +void +init_ruby_module() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (module) + return; + + VALUE opencv = rb_module_opencv(); + module = rb_define_module_under(opencv, "Curve"); + rb_define_method(module, "closed?", RUBY_METHOD_FUNC(rb_closed_q), 0); + rb_define_method(module, "convex?", RUBY_METHOD_FUNC(rb_convex_q), 0); + rb_define_method(module, "hole?", RUBY_METHOD_FUNC(rb_hole_q), 0); + rb_define_method(module, "simple?", RUBY_METHOD_FUNC(rb_simple_q), 0); + rb_define_method(module, "arc_length", RUBY_METHOD_FUNC(rb_arc_length), -1); +} + +__NAMESPACE_END_CURVE +__NAMESPACE_END_OPENCV + diff --git a/ext/curve.h b/ext/opencv/curve.h similarity index 86% rename from ext/curve.h rename to ext/opencv/curve.h index ededafa6..28ec556b 100644 --- a/ext/curve.h +++ b/ext/opencv/curve.h @@ -10,9 +10,9 @@ #ifndef RUBY_OPENCV_CVSEQ_CURVE_H #define RUBY_OPENCV_CVSEQ_CURVE_H -#include"opencv.h" +#include "opencv.h" -#define __NAMESPACE_BEGIN_CURVE namespace mCurve{ +#define __NAMESPACE_BEGIN_CURVE namespace mCurve { #define __NAMESPACE_END_CURVE } __NAMESPACE_BEGIN_OPENCV @@ -20,7 +20,7 @@ __NAMESPACE_BEGIN_CURVE VALUE rb_module(); -void define_ruby_module(); +void init_ruby_module(); VALUE rb_closed_q(VALUE self); VALUE rb_convex_q(VALUE self); diff --git a/ext/cvavgcomp.cpp b/ext/opencv/cvavgcomp.cpp similarity index 67% rename from ext/cvavgcomp.cpp rename to ext/opencv/cvavgcomp.cpp index 4ce69ed3..ec646488 100644 --- a/ext/cvavgcomp.cpp +++ b/ext/opencv/cvavgcomp.cpp @@ -11,13 +11,7 @@ /* * Document-class: OpenCV::CvAvgComp * - * CvRect with parameter "neighbors". - * CvHaarClassifierCascade#detect_object. - * - * typedef struct CvAvgComp{ - * CvRect rect; - * int neighbors; - * } + * CvRect with parameter "neighbors" */ __NAMESPACE_BEGIN_OPENCV __NAMESPACE_BEGIN_AVGCOMP @@ -30,23 +24,6 @@ rb_class() return rb_klass; } -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * cvrect = rb_define_class_under(opencv, "CvRect", rb_cObject); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(), cvrect = cCvRect::rb_class(); - rb_klass = rb_define_class_under(opencv, "CvAvgComp", cvrect); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_method(rb_klass, "neighbors", RUBY_METHOD_FUNC(rb_neighbors), 0); -} - VALUE rb_allocate(VALUE klass) { @@ -55,12 +32,32 @@ rb_allocate(VALUE klass) } /* - * Return neighbors. + * Return neighbors + * @overload neighbors + * @return [Integer] neighbors */ VALUE rb_neighbors(VALUE self) { - return INT2FIX(CVAVGCOMP(self)->neighbors); + return INT2NUM(CVAVGCOMP(self)->neighbors); +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); + VALUE cvrect = rb_define_class_under(opencv, "CvRect", rb_cObject); +#endif + + if (rb_klass) + return; + + VALUE opencv = rb_module_opencv(), cvrect = cCvRect::rb_class(); + rb_klass = rb_define_class_under(opencv, "CvAvgComp", cvrect); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_method(rb_klass, "neighbors", RUBY_METHOD_FUNC(rb_neighbors), 0); } __NAMESPACE_END_AVGCOMP diff --git a/ext/cvavgcomp.h b/ext/opencv/cvavgcomp.h similarity index 89% rename from ext/cvavgcomp.h rename to ext/opencv/cvavgcomp.h index 5eb6f828..a29d7d00 100644 --- a/ext/cvavgcomp.h +++ b/ext/opencv/cvavgcomp.h @@ -10,7 +10,7 @@ #ifndef RUBY_OPENCV_AVGCOMP_H #define RUBY_OPENCV_AVGCOMP_H -#define __NAMESPACE_BEGIN_AVGCOMP namespace cCvAvgComp{ +#define __NAMESPACE_BEGIN_AVGCOMP namespace cCvAvgComp { #define __NAMESPACE_END_AVGCOMP } #include @@ -20,7 +20,7 @@ __NAMESPACE_BEGIN_AVGCOMP VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_allocate(VALUE klass); VALUE rb_neighbors(VALUE self); diff --git a/ext/opencv/cvbox2d.cpp b/ext/opencv/cvbox2d.cpp new file mode 100644 index 00000000..bf39e04d --- /dev/null +++ b/ext/opencv/cvbox2d.cpp @@ -0,0 +1,195 @@ +/************************************************************ + + cvbox2d.cpp - + + $Author: lsxi $ + + Copyright (C) 2005-2006 Masakazu Yonekura + +************************************************************/ +#include "cvbox2d.h" +/* + * Document-class: OpenCV::CvBox2D + * + * Stores coordinates of a rotated rectangle. + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVBOX2D + +VALUE rb_klass; + +VALUE +rb_class() +{ + return rb_klass; +} + +VALUE +rb_allocate(VALUE klass) +{ + CvBox2D *ptr; + return Data_Make_Struct(klass, CvBox2D, 0, -1, ptr); +} + +/* + * Create a box + * @overload new(center=nil, size=nil, angle=nil) + * @param center [CvPoint2D32f,nil] Center of the box + * @param size [CvSize,nil] Size of the box + * @param angle [Number,nil] Angle between the horizontal axis and the first side in degrees + * @return [CvBox2D] New box + */ +VALUE +rb_initialize(int argc, VALUE *argv, VALUE self) +{ + VALUE center, size, angle; + CvBox2D* self_ptr = CVBOX2D(self); + rb_scan_args(argc, argv, "03", ¢er, &size, &angle); + + if (!NIL_P(center)) { + self_ptr->center = VALUE_TO_CVPOINT2D32F(center); + } + if (!NIL_P(size)) { + self_ptr->size = VALUE_TO_CVSIZE2D32F(size); + self_ptr->angle = NUM2DBL(angle); + } + + return self; +} + +/* + * Returns center point of the box + * @overload center + * @return [CvPoint2D32f] Center of the box + */ +VALUE +rb_center(VALUE self) +{ + return REFER_OBJECT(cCvPoint2D32f::rb_class(), &CVBOX2D(self)->center, self); +} + +/* + * Set center point of the box + * @overload center=value + * @param value [CvPoint2D32f] Center of the box + * @return [CvBox2D] self + */ +VALUE +rb_set_center(VALUE self, VALUE value) +{ + CVBOX2D(self)->center = VALUE_TO_CVPOINT2D32F(value); + return self; +} + +/* + * Returns size of the box + * @overload size + * @return [CvSize2D32f] Size of the box + */ +VALUE +rb_size(VALUE self) +{ + return REFER_OBJECT(cCvSize2D32f::rb_class(), &CVBOX2D(self)->size, self); +} + +/* + * Set size of the box + * @overload size=value + * @param value [CvSize2D32f] Size of the box + * @return [CvBox2D] self + */ +VALUE +rb_set_size(VALUE self, VALUE value) +{ + CVBOX2D(self)->size = VALUE_TO_CVSIZE2D32F(value); + return self; +} + +/* + * Returns angle of the box + * @overload angle + * @return [Float] Angle of the box + */ +VALUE +rb_angle(VALUE self) +{ + return rb_float_new(CVBOX2D(self)->angle); +} + +/* + * Set angle of the box + * @overload angle=value + * @param value [Number] Angle of the box + * @return [CvBox2D] self + */ +VALUE +rb_set_angle(VALUE self, VALUE value) +{ + CVBOX2D(self)->angle = NUM2DBL(value); + return self; +} + +/* + * Find box vertices + * @overload points + * @return [Array] Vertices of the box + * @opencv_func cvBoxPoints + */ +VALUE +rb_points(VALUE self) +{ + const int n = 4; + CvPoint2D32f p[n]; + try { + cvBoxPoints(*CVBOX2D(self), p); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + VALUE points = rb_ary_new2(n); + for (int i = 0; i < n; ++i) { + rb_ary_store(points, i, cCvPoint2D32f::new_object(p[i])); + } + return points; +} + +VALUE +new_object() +{ + return rb_allocate(cCvBox2D::rb_class()); +} + +VALUE +new_object(CvBox2D box) +{ + VALUE object = rb_allocate(rb_klass); + *CVBOX2D(object) = box; + return object; +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + + VALUE opencv = rb_module_opencv(); + rb_klass = rb_define_class_under(opencv, "CvBox2D", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "center", RUBY_METHOD_FUNC(rb_center), 0); + rb_define_method(rb_klass, "center=", RUBY_METHOD_FUNC(rb_set_center), 1); + rb_define_method(rb_klass, "size", RUBY_METHOD_FUNC(rb_size), 0); + rb_define_method(rb_klass, "size=", RUBY_METHOD_FUNC(rb_set_size), 1); + rb_define_method(rb_klass, "angle", RUBY_METHOD_FUNC(rb_angle), 0); + rb_define_method(rb_klass, "angle=", RUBY_METHOD_FUNC(rb_set_angle), 1); + rb_define_method(rb_klass, "points", RUBY_METHOD_FUNC(rb_points), 0); +} + +__NAMESPACE_END_CVBOX2D +__NAMESPACE_END_OPENCV diff --git a/ext/cvbox2d.h b/ext/opencv/cvbox2d.h similarity index 59% rename from ext/cvbox2d.h rename to ext/opencv/cvbox2d.h index b069ca74..fa1432a9 100644 --- a/ext/cvbox2d.h +++ b/ext/opencv/cvbox2d.h @@ -10,9 +10,9 @@ #ifndef RUBY_OPENCV_CVBOX2D_H #define RUBY_OPENCV_CVBOX2D_H -#include"opencv.h" +#include "opencv.h" -#define __NAMESPACE_BEGIN_CVBOX2D namespace cCvBox2D{ +#define __NAMESPACE_BEGIN_CVBOX2D namespace cCvBox2D { #define __NAMESPACE_END_CVBOX2D } __NAMESPACE_BEGIN_OPENCV @@ -20,13 +20,17 @@ __NAMESPACE_BEGIN_CVBOX2D VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_allocate(VALUE klass); +VALUE rb_initialize(int argc, VALUE *argv, VALUE self); VALUE rb_center(VALUE self); +VALUE rb_set_center(VALUE self, VALUE value); VALUE rb_size(VALUE self); +VALUE rb_set_size(VALUE self, VALUE value); VALUE rb_angle(VALUE self); +VALUE rb_set_angle(VALUE self, VALUE value); VALUE rb_points(VALUE self); VALUE new_object(); @@ -34,18 +38,22 @@ VALUE new_object(CvBox2D box); __NAMESPACE_END_CVBOX2D -inline CvBox2D *CVBOX2D(VALUE object){ +inline CvBox2D* +CVBOX2D(VALUE object){ CvBox2D *ptr; Data_Get_Struct(object, CvBox2D, ptr); return ptr; } -inline CvBox2D VALUE_TO_CVBOX2D(VALUE object){ - if(rb_obj_is_kind_of(object, cCvBox2D::rb_class())) { +inline CvBox2D +VALUE_TO_CVBOX2D(VALUE object){ + if (rb_obj_is_kind_of(object, cCvBox2D::rb_class())) { return *CVBOX2D(object); - }else{ - rb_raise(rb_eTypeError, "require %s or compatible object.", rb_class2name(cCvBox2D::rb_class())); } + else { + raise_typeerror(object, cCvBox2D::rb_class()); + } + throw "Should never reach here"; } __NAMESPACE_END_OPENCV diff --git a/ext/opencv/cvcapture.cpp b/ext/opencv/cvcapture.cpp new file mode 100644 index 00000000..cdac3e99 --- /dev/null +++ b/ext/opencv/cvcapture.cpp @@ -0,0 +1,633 @@ +/************************************************************ + + cvcapture.cpp - + + $Author: lsxi $ + + Copyright (C) 2005-2006 Masakazu Yonekura + +************************************************************/ +#include "cvcapture.h" +/* + * Document-class: OpenCV::CvCapture + * + * Class for video capturing from video files or cameras + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVCAPTURE + +VALUE rb_klass; + +VALUE +rb_class() +{ + return rb_klass; +} + +void +cvcapture_free(void *ptr) +{ + if (ptr) { + sCvCapture* scap = (sCvCapture*)ptr; + if (scap->opened) + cvReleaseCapture(&scap->ptr); + delete scap; + } +} + +/* + * Open video file or a capturing device for video capturing + * @scope class + * @overload open(dev = nil) + * @param dev [String,Integer,Simbol,nil] Video capturing device + * * If dev is a string (i.e "stream.avi"), reads video stream from a file. + * * If dev is a number or symbol (included in CvCapture::INTERFACE), reads video stream from a device. + * * If dev is a nil, same as CvCapture.open(:any) + * @return [CvCapture] Opened CvCapture instance + * @opencv_func cvCaptureFromCAM + * @opencv_func cvCaptureFromFile + */ +VALUE +rb_open(int argc, VALUE *argv, VALUE self) +{ + VALUE device; + rb_scan_args(argc, argv, "01", &device); + CvCapture *capture = 0; + sCvCapture *scap = new sCvCapture(); + try { + switch (TYPE(device)) { + case T_STRING: + capture = cvCaptureFromFile(StringValueCStr(device)); + break; + case T_FIXNUM: + capture = cvCaptureFromCAM(FIX2INT(device)); + break; + case T_SYMBOL: { + VALUE cap_index = rb_hash_lookup(rb_const_get(rb_class(), rb_intern("INTERFACE")), device); + if (NIL_P(cap_index)) + rb_raise(rb_eArgError, "undefined interface."); + capture = cvCaptureFromCAM(NUM2INT(cap_index)); + break; + } + case T_NIL: + capture = cvCaptureFromCAM(CV_CAP_ANY); + break; + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + if (!capture) + rb_raise(rb_eStandardError, "Invalid capture format."); + scap->ptr = capture; + scap->opened = true; + return Data_Wrap_Struct(rb_klass, 0, cvcapture_free, scap); +} + +/* + * Releases an opened video file or a capturing device + * @return [boolean] False if the device was already closed + */ + +VALUE +rb_close(VALUE self) +{ + sCvCapture *scap; + Data_Get_Struct(self, sCvCapture, scap); + if (scap->opened) { + scap->opened = false; + cvReleaseCapture(&scap->ptr); + return true; + } else + return false; +} + +/* + * Grabs the next frame from video file or capturing device. + * @overload grab + * @return [Boolean] If grabbing a frame successed, returns true, otherwise returns false. + * @opencv_func cvGrabFrame + */ +VALUE +rb_grab(VALUE self) +{ + int grab = 0; + try { + grab = cvGrabFrame(CVCAPTURE(self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return grab ? Qtrue : Qfalse; +} + +/* + * Decodes and returns the grabbed video frame. + * @overload retrieve + * @return [IplImage] Grabbed video frame + * @return [nil] Failed to grabbing a frame + * @opencv_func cvRetrieveFrame + */ +VALUE +rb_retrieve(VALUE self) +{ + VALUE image = Qnil; + IplImage *frame = NULL; + try { + if (!(frame = cvRetrieveFrame(CVCAPTURE(self)))) { + return Qnil; + } + image = cIplImage::new_object(frame->width, frame->height, + CV_MAKETYPE(IPL2CV_DEPTH(frame->depth), frame->nChannels)); + if (frame->origin == IPL_ORIGIN_TL) { + cvCopy(frame, CVARR(image)); + } + else { + cvFlip(frame, CVARR(image)); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return image; + +} + +/* + * Grabs, decodes and returns the next video frame. + * @overload query + * @return [IplImage] Next video frame + * @return [nil] Failed to read next video frame + * @opencv_func cvQueryFrame + */ +VALUE +rb_query(VALUE self) +{ + VALUE image = Qnil; + IplImage *frame = NULL; + try { + if (!(frame = cvQueryFrame(CVCAPTURE(self)))) { + return Qnil; + } + image = cIplImage::new_object(frame->width, frame->height, + CV_MAKETYPE(IPL2CV_DEPTH(frame->depth), frame->nChannels)); + if (frame->origin == IPL_ORIGIN_TL) { + cvCopy(frame, CVARR(image)); + } + else { + cvFlip(frame, CVARR(image)); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return image; +} + +VALUE +rb_get_capture_property(VALUE self, int id) +{ + double result = 0; + try { + result = cvGetCaptureProperty(CVCAPTURE(self), id); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_float_new(result); +} + +VALUE +rb_set_capture_property(VALUE self, int id, VALUE value) +{ + double result = 0; + try { + result = cvSetCaptureProperty(CVCAPTURE(self), id, NUM2DBL(value)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_float_new(result); +} + +/* + * Get film current position in milliseconds or video capture timestamp. + * @overload millisecond + * @return [Number] Current position of the video file in milliseconds or video capture timestamp + * @opencv_func cvGetCaptureProperty (propId=CV_CAP_PROP_POS_MSEC) + */ +VALUE +rb_get_millisecond(VALUE self) +{ + return rb_get_capture_property(self, CV_CAP_PROP_POS_MSEC); +} + +/* + * Set film current position in milliseconds or video capture timestamp. + * @overload millisecond=value + * @param value [Number] Position in milliseconds or video capture timestamp. + * @return [Number] + * @opencv_func cvSetCaptureProperty (propId=CV_CAP_PROP_POS_MSEC) + */ +VALUE +rb_set_millisecond(VALUE self, VALUE value) +{ + return rb_set_capture_property(self, CV_CAP_PROP_POS_MSEC, value); +} + +/* + * Get 0-based index of the frame to be decoded/captured next + * @overload frames + * @return [Number] 0-based index of the frame to be decoded/captured next + * @opencv_func cvGetCaptureProperty (propId=CV_CAP_PROP_POS_FRAMES) + */ +VALUE +rb_get_frames(VALUE self) +{ + return rb_get_capture_property(self, CV_CAP_PROP_POS_FRAMES); +} + +/* + * Set 0-based index of the frame to be decoded/captured next + * @overload frames=value + * @param value [Number] 0-based index of the frame to be decoded/captured next + * @return [Number] + * @opencv_func cvSetCaptureProperty (propId=CV_CAP_PROP_POS_FRAMES) + */ +VALUE +rb_set_frames(VALUE self, VALUE value) +{ + return rb_set_capture_property(self, CV_CAP_PROP_POS_FRAMES, value); +} +/* + * Get relative position of video file + * @overload avi_ratio + * @return [Number] Relative position of video file (0: Start of the film, 1: End of the film) + * @opencv_func cvGetCaptureProperty (propId=CV_CAP_PROP_POS_AVI_RATIO) + */ +VALUE +rb_get_avi_ratio(VALUE self) +{ + return rb_get_capture_property(self, CV_CAP_PROP_POS_AVI_RATIO); +} +/* + * Set relative position of video file + * @overload avi_ratio=value + * @param value [Number] Relative position of video file (0: Start of the film, 1: End of the film) + * @return [Number] + * @opencv_func cvSetCaptureProperty (propId=CV_CAP_PROP_POS_AVI_RATIO) + */ +VALUE +rb_set_avi_ratio(VALUE self, VALUE value) +{ + return rb_set_capture_property(self, CV_CAP_PROP_POS_AVI_RATIO, value); +} + +/* + * Get size of frames in the video stream. + * @overload size + * @return [Size] Size of frames in the video stream. + * @opencv_func cvGetCaptureProperty (propId=CV_CAP_PROP_FRAME_WIDTH,CV_CAP_PROP_FRAME_HEIGHT) + */ +VALUE +rb_get_size(VALUE self) +{ + CvSize size; + try { + CvCapture* self_ptr = CVCAPTURE(self); + size = cvSize((int)cvGetCaptureProperty(self_ptr, CV_CAP_PROP_FRAME_WIDTH), + (int)cvGetCaptureProperty(self_ptr, CV_CAP_PROP_FRAME_HEIGHT)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return cCvSize::new_object(size); +} + +/* + * Set size of frames in the video stream. + * @overload size=value + * @param value [CvSize] Size of frames + * @return [Number] + * @opencv_func cvSetCaptureProperty (propId=CV_CAP_PROP_FRAME_WIDTH,CV_CAP_PROP_FRAME_HEIGHT) + */ +VALUE +rb_set_size(VALUE self, VALUE value) +{ + double result = 0; + CvSize size = VALUE_TO_CVSIZE(value); + try { + CvCapture* self_ptr = CVCAPTURE(self); + cvSetCaptureProperty(self_ptr, CV_CAP_PROP_FRAME_WIDTH, size.width); + result = cvSetCaptureProperty(self_ptr, CV_CAP_PROP_FRAME_HEIGHT, size.height); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return DBL2NUM(result); +} + +/* + * Get width of frames in the video stream. + * @overload width + * @return [Number] Width of frames in the video stream. + * @opencv_func cvGetCaptureProperty (propId=CV_CAP_FRAME_WIDTH) + */ +VALUE +rb_get_width(VALUE self) +{ + return rb_get_capture_property(self, CV_CAP_PROP_FRAME_WIDTH); +} + +/* + * Set width of frames in the video stream. + * @overload width=value + * @param value [Number] Width of frames + * @return [Number] + * @opencv_func cvSetCaptureProperty (propId=CV_CAP_PROP_FRAME_WIDTH) + */ +VALUE +rb_set_width(VALUE self, VALUE value) +{ + return rb_set_capture_property(self, CV_CAP_PROP_FRAME_WIDTH, value); +} + +/* + * Get height of frames in the video stream. + * @overload height + * @return [Number] Height of frames in the video stream. + * @opencv_func cvGetCaptureProperty (propId=CV_CAP_PROP_FRAME_HEIGHT) + */ +VALUE +rb_get_height(VALUE self) +{ + return rb_get_capture_property(self, CV_CAP_PROP_FRAME_HEIGHT); +} + +/* + * Set height of frames in the video stream. + * @overload height=value + * @param value [Number] Height of frames + * @return [Number] + * @opencv_func cvSetCaptureProperty (propId=CV_CAP_PROP_FRAME_HEIGHT) + */ +VALUE +rb_set_height(VALUE self, VALUE value) +{ + return rb_set_capture_property(self, CV_CAP_PROP_FRAME_HEIGHT, value); +} + +/* + * Get frame rate + * @overload fps + * @return [Number] Frame rate + * @opencv_func cvGetCaptureProperty (propId=CV_CAP_PROP_FPS) + */ +VALUE +rb_get_fps(VALUE self) +{ + return rb_get_capture_property(self, CV_CAP_PROP_FPS); +} + +/* + * Set frame rate + * @overload fps=value + * @param value [Number] Frame rate + * @return [Number] + * @opencv_func cvSetCaptureProperty (propId=CV_CAP_PROP_FPS) + */ +VALUE +rb_set_fps(VALUE self, VALUE value) +{ + return rb_set_capture_property(self, CV_CAP_PROP_FPS, value); +} + +/* + * Get 4 character code of codec. see http://www.fourcc.org/ + * @overload fourcc + * @return [Number] Codec code + * @opencv_func cvGetCaptureProperty (propId=CV_CAP_PROP_FOURCC) + */ +VALUE +rb_get_fourcc(VALUE self) +{ + char str[4]; + double fourcc = cvGetCaptureProperty(CVCAPTURE(self), CV_CAP_PROP_FOURCC); + sprintf(str, "%s", (char*)&fourcc); + return rb_str_new2(str); +} + +/* + * Get number of frames in video file. + * @overload frame_count + * @return [Number] Number of frames + * @opencv_func cvGetCaptureProperty (propId=CV_CAP_PROP_FRAME_COUNT) + */ +VALUE +rb_get_frame_count(VALUE self) +{ + return rb_get_capture_property(self, CV_CAP_PROP_FRAME_COUNT); +} + +/* + * Get format of images returned by CvCapture#retrieve + * @overload format + * @return [Number] format + * @opencv_func cvGetCaptureProperty (propId=CV_CAP_PROP_FORMAT) + */ +VALUE +rb_get_format(VALUE self) +{ + return rb_get_capture_property(self, CV_CAP_PROP_FORMAT); +} + +/* + * Get a backend-specific value indicating the current capture mode + * @overload mode + * @return [Number] Backend-specific value indicating the current capture mode + * @opencv_func cvGetCaptureProperty (propId=CV_CAP_PROP_MODE) + */ +VALUE +rb_get_mode(VALUE self) +{ + return rb_get_capture_property(self, CV_CAP_PROP_MODE); +} + +/* + * Get brightness of the image (only for cameras) + * @overload brightness + * @return [Number] Brightness + * @opencv_func cvGetCaptureProperty (propId=CV_CAP_PROP_BRIGHTNESS) + */ +VALUE +rb_get_brightness(VALUE self) +{ + return rb_get_capture_property(self, CV_CAP_PROP_BRIGHTNESS); +} + +/* + * Get contrast of the image (only for cameras) + * @overload contrast + * @return [Number] Contrast + * @opencv_func cvGetCaptureProperty (propId=CV_CAP_PROP_CONTRAST) + */ +VALUE +rb_get_contrast(VALUE self) +{ + return rb_get_capture_property(self, CV_CAP_PROP_CONTRAST); +} + +/* + * Get saturation of the image (only for cameras) + * @overload saturation + * @return [Number] Saturation + * @opencv_func cvGetCaptureProperty (propId=CV_CAP_PROP_SATURATION) + */ +VALUE +rb_get_saturation(VALUE self) +{ + return rb_get_capture_property(self, CV_CAP_PROP_SATURATION); +} +/* + * Get hue of the image (only for cameras) + * @overload hue + * @return [Number] Hue + * @opencv_func cvGetCaptureProperty (propId=CV_CAP_PROP_HUE) + */ +VALUE +rb_get_hue(VALUE self) +{ + return rb_get_capture_property(self, CV_CAP_PROP_HUE); +} + +/* + * Get gain of the image (only for cameras) + * @overload gain + * @return [Number] Gain + * @opencv_func cvGetCaptureProperty (propId=CV_CAP_PROP_GAIN) + */ +VALUE +rb_get_gain(VALUE self) +{ + return rb_get_capture_property(self, CV_CAP_PROP_GAIN); +} + +/* + * Get exposure (only for cameras) + * @overload exposure + * @return [Number] Exposure + * @opencv_func cvGetCaptureProperty (propId=CV_CAP_PROP_EXPOSURE) + */ +VALUE +rb_get_exposure(VALUE self) +{ + return rb_get_capture_property(self, CV_CAP_PROP_EXPOSURE); +} + +/* + * Get boolean flags indicating whether images should be converted to RGB + * @overload convert_rgb + * @return [Boolean] Whether images should be converted to RGB + * @opencv_func cvGetCaptureProperty (propId=CV_CAP_PROP_CONVERT_RGB) + */ +VALUE +rb_get_convert_rgb(VALUE self) +{ + int flag = 0; + try { + flag = (int)cvGetCaptureProperty(CVCAPTURE(self), CV_CAP_PROP_CONVERT_RGB); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return flag ? Qtrue : Qfalse; +} + +/* + * Get rectification flag for stereo cameras (note: only supported by DC1394 v 2.x backend currently) + * @overload rectification + * @return [Number] Rectification flag + * @opencv_func cvGetCaptureProperty (propId=CV_CAP_PROP_RECTIFICATION) + */ +VALUE +rb_get_rectification(VALUE self) +{ + return rb_get_capture_property(self, CV_CAP_PROP_RECTIFICATION); +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + + VALUE opencv = rb_module_opencv(); + + rb_klass = rb_define_class_under(opencv, "CvCapture", rb_cData); + + VALUE video_interface = rb_hash_new(); + /* + * :any, :mil, :vfw, :v4l, :v4l2, :fireware, :ieee1394, :dc1394, :cmu1394, + * :stereo, :tyzx, :tyzx_left, :tyzx_right, :tyzx_color, :tyzx_z, :qt, :qtuicktime + */ + rb_define_const(rb_klass, "INTERFACE", video_interface); + rb_hash_aset(video_interface, ID2SYM(rb_intern("any")), INT2FIX(CV_CAP_ANY)); + rb_hash_aset(video_interface, ID2SYM(rb_intern("mil")), INT2FIX(CV_CAP_MIL)); + rb_hash_aset(video_interface, ID2SYM(rb_intern("vfw")), INT2FIX(CV_CAP_VFW)); + rb_hash_aset(video_interface, ID2SYM(rb_intern("v4l")), INT2FIX(CV_CAP_V4L)); + rb_hash_aset(video_interface, ID2SYM(rb_intern("v4l2")), INT2FIX(CV_CAP_V4L2)); + rb_hash_aset(video_interface, ID2SYM(rb_intern("fireware")), INT2FIX(CV_CAP_FIREWARE)); + rb_hash_aset(video_interface, ID2SYM(rb_intern("ieee1394")), INT2FIX(CV_CAP_IEEE1394)); + rb_hash_aset(video_interface, ID2SYM(rb_intern("dc1394")), INT2FIX(CV_CAP_DC1394)); + rb_hash_aset(video_interface, ID2SYM(rb_intern("cmu1394")), INT2FIX(CV_CAP_CMU1394)); + rb_hash_aset(video_interface, ID2SYM(rb_intern("stereo")), INT2FIX(CV_CAP_STEREO)); + rb_hash_aset(video_interface, ID2SYM(rb_intern("tyzx")), INT2FIX(CV_CAP_TYZX)); + rb_hash_aset(video_interface, ID2SYM(rb_intern("tyzx_left")), INT2FIX(CV_TYZX_LEFT)); + rb_hash_aset(video_interface, ID2SYM(rb_intern("tyzx_right")), INT2FIX(CV_TYZX_RIGHT)); + rb_hash_aset(video_interface, ID2SYM(rb_intern("tyzx_color")), INT2FIX(CV_TYZX_COLOR)); + rb_hash_aset(video_interface, ID2SYM(rb_intern("tyzx_z")), INT2FIX(CV_TYZX_Z)); + rb_hash_aset(video_interface, ID2SYM(rb_intern("qt")), INT2FIX(CV_CAP_QT)); + rb_hash_aset(video_interface, ID2SYM(rb_intern("quicktime")), INT2FIX(CV_CAP_QT)); + + rb_define_singleton_method(rb_klass, "open", RUBY_METHOD_FUNC(rb_open), -1); + rb_define_method(rb_klass, "close", RUBY_METHOD_FUNC(rb_close), 0); + + rb_define_method(rb_klass, "grab", RUBY_METHOD_FUNC(rb_grab), 0); + rb_define_method(rb_klass, "retrieve", RUBY_METHOD_FUNC(rb_retrieve), 0); + rb_define_method(rb_klass, "query", RUBY_METHOD_FUNC(rb_query), 0); + rb_define_method(rb_klass, "millisecond", RUBY_METHOD_FUNC(rb_get_millisecond), 0); + rb_define_method(rb_klass, "millisecond=", RUBY_METHOD_FUNC(rb_set_millisecond), 1); + rb_define_method(rb_klass, "frames", RUBY_METHOD_FUNC(rb_get_frames), 0); + rb_define_method(rb_klass, "frames=", RUBY_METHOD_FUNC(rb_set_frames), 1); + rb_define_method(rb_klass, "avi_ratio", RUBY_METHOD_FUNC(rb_get_avi_ratio), 0); + rb_define_method(rb_klass, "avi_ratio=", RUBY_METHOD_FUNC(rb_set_avi_ratio), 1); + rb_define_method(rb_klass, "size", RUBY_METHOD_FUNC(rb_get_size), 0); + rb_define_method(rb_klass, "size=", RUBY_METHOD_FUNC(rb_set_size), 1); + rb_define_method(rb_klass, "width", RUBY_METHOD_FUNC(rb_get_width), 0); + rb_define_method(rb_klass, "width=", RUBY_METHOD_FUNC(rb_set_width), 1); + rb_define_method(rb_klass, "height", RUBY_METHOD_FUNC(rb_get_height), 0); + rb_define_method(rb_klass, "height=", RUBY_METHOD_FUNC(rb_set_height), 1); + rb_define_method(rb_klass, "fps", RUBY_METHOD_FUNC(rb_get_fps), 0); + rb_define_method(rb_klass, "fps=", RUBY_METHOD_FUNC(rb_set_fps), 1); + rb_define_method(rb_klass, "fourcc", RUBY_METHOD_FUNC(rb_get_fourcc), 0); + rb_define_method(rb_klass, "frame_count", RUBY_METHOD_FUNC(rb_get_frame_count), 0); + rb_define_method(rb_klass, "format", RUBY_METHOD_FUNC(rb_get_format), 0); + rb_define_method(rb_klass, "mode", RUBY_METHOD_FUNC(rb_get_mode), 0); + rb_define_method(rb_klass, "brightness", RUBY_METHOD_FUNC(rb_get_brightness), 0); + rb_define_method(rb_klass, "contrast", RUBY_METHOD_FUNC(rb_get_contrast), 0); + rb_define_method(rb_klass, "saturation", RUBY_METHOD_FUNC(rb_get_saturation), 0); + rb_define_method(rb_klass, "hue", RUBY_METHOD_FUNC(rb_get_hue), 0); + rb_define_method(rb_klass, "gain", RUBY_METHOD_FUNC(rb_get_gain), 0); + rb_define_method(rb_klass, "exposure", RUBY_METHOD_FUNC(rb_get_exposure), 0); + rb_define_method(rb_klass, "convert_rgb", RUBY_METHOD_FUNC(rb_get_convert_rgb), 0); + rb_define_method(rb_klass, "rectification", RUBY_METHOD_FUNC(rb_get_rectification), 0); +} + +__NAMESPACE_END_CVCAPTURE +__NAMESPACE_END_OPENCV + diff --git a/ext/opencv/cvcapture.h b/ext/opencv/cvcapture.h new file mode 100644 index 00000000..3e758d53 --- /dev/null +++ b/ext/opencv/cvcapture.h @@ -0,0 +1,82 @@ +/************************************************************ + + cvcapture.h - + + $Author: lsxi $ + + Copyright (C) 2005-2006 Masakazu Yonekura + +************************************************************/ +#ifndef RUBY_OPENCV_CVCAPTURE_H +#define RUBY_OPENCV_CVCAPTURE_H + +#include "opencv.h" + +#define __NAMESPACE_BEGIN_CVCAPTURE namespace cCvCapture { +#define __NAMESPACE_END_CVCAPTURE } + +__NAMESPACE_BEGIN_OPENCV + +typedef struct { + CvCapture* ptr; + bool opened; +} sCvCapture; + +__NAMESPACE_BEGIN_CVCAPTURE + + +VALUE rb_class(); + +void init_ruby_class(); + +void cvcapture_free(void *ptr); +VALUE rb_open(int argc, VALUE *argv, VALUE klass); + +VALUE rb_close(VALUE self); + +VALUE rb_grab(VALUE self); +VALUE rb_retrieve(VALUE self); +VALUE rb_query(VALUE self); + +VALUE rb_get_millisecond(VALUE self); +VALUE rb_set_millisecond(VALUE self, VALUE value); +VALUE rb_get_frames(VALUE self); +VALUE rb_set_frames(VALUE self, VALUE value); +VALUE rb_get_avi_ratio(VALUE self); +VALUE rb_set_avi_ratio(VALUE self, VALUE value); +VALUE rb_get_size(VALUE self); +VALUE rb_set_size(VALUE self, VALUE value); +VALUE rb_get_width(VALUE self); +VALUE rb_set_width(VALUE self, VALUE value); +VALUE rb_get_height(VALUE self); +VALUE rb_set_height(VALUE self, VALUE value); +VALUE rb_get_fps(VALUE self); +VALUE rb_set_fps(VALUE self, VALUE value); +VALUE rb_get_fourcc(VALUE self); +VALUE rb_get_frame_count(VALUE self); +VALUE rb_get_format(VALUE self); +VALUE rb_get_mode(VALUE self); +VALUE rb_get_brightness(VALUE self); +VALUE rb_get_contrast(VALUE self); +VALUE rb_get_saturation(VALUE self); +VALUE rb_get_hue(VALUE self); +VALUE rb_get_gain(VALUE self); +VALUE rb_get_exposure(VALUE self); +VALUE rb_get_convert_rgb(VALUE self); +VALUE rb_get_rectification(VALUE self); + +__NAMESPACE_END_CVCAPTURE + + +inline CvCapture* +CVCAPTURE(VALUE object) { + sCvCapture *scap; + Data_Get_Struct(object, sCvCapture, scap); + if (!scap->opened) + rb_raise(rb_eIOError, "Resource is not available!"); + return scap->ptr; +} + +__NAMESPACE_END_OPENCV + +#endif // RUBY_OPENCV_CVCAPTURE_H diff --git a/ext/opencv/cvchain.cpp b/ext/opencv/cvchain.cpp new file mode 100644 index 00000000..9fdc53bb --- /dev/null +++ b/ext/opencv/cvchain.cpp @@ -0,0 +1,233 @@ +/************************************************************ + + cvchain.cpp - + + $Author: lsxi $ + + Copyright (C) 2007 Masakazu Yonekura + +************************************************************/ +#include "cvchain.h" +/* + * Document-class: OpenCV::CvChain + * + * Freeman chain code + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVCHAIN + +#define APPROX_CHAIN_OPTION(op) rb_get_option_table(rb_klass, "APPROX_CHAIN_OPTION", op) +#define APPROX_CHAIN_METHOD(op) CVMETHOD("APPROX_CHAIN_METHOD", LOOKUP_HASH(op, "method"), CV_CHAIN_APPROX_SIMPLE) +#define APPROX_CHAIN_PARAMETER(op) NUM2INT(LOOKUP_HASH(op, "parameter")) +#define APPROX_CHAIN_MINIMAL_PERIMETER(op) NUM2INT(LOOKUP_HASH(op, "minimal_perimeter")) +#define APPROX_CHAIN_RECURSIVE(op) TRUE_OR_FALSE(LOOKUP_HASH(op, "recursive")) + +VALUE rb_klass; + +VALUE +rb_class() +{ + return rb_klass; +} + +VALUE +rb_allocate(VALUE klass) +{ + return Data_Wrap_Struct(klass, mark_root_object, unregister_object, NULL); +} + +/* + * Create a new chain code + * @overload new(storage=nil) + * @param storage [CvMemStorage,nil] Sequence location (If storage is nil, allocates a new storage automatically) + * @return [CvChain] New CvChain instance + * @opencv_func cvCreateSeq (seq_flags=CV_SEQ_ELTYPE_CODE) + */ +VALUE +rb_initialize(int argc, VALUE *argv, VALUE self) +{ + CvMemStorage *storage; + VALUE storage_value; + if (rb_scan_args(argc, argv, "01", &storage_value) > 0) { + storage_value = CHECK_CVMEMSTORAGE(storage_value); + storage = CVMEMSTORAGE(storage_value); + } + else + storage = rb_cvCreateMemStorage(0); + try { + DATA_PTR(self) = (CvChain*)cvCreateSeq(CV_SEQ_ELTYPE_CODE, sizeof(CvChain), + sizeof(int), storage); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + CvSeq* self_ptr = CVSEQ(self); + cCvSeq::register_elem_class(self_ptr, rb_cInteger); + register_root_object(self_ptr, storage_value); + + return self; +} + +/* + * Returns Freeman chain code origin + * @overload origin + * @return [CvPoint] Origin of the chain code + */ +VALUE +rb_origin(VALUE self) +{ + return cCvPoint::new_object(CVCHAIN(self)->origin); +} + +/* + * Set Freeman chain code origin + * @overload origin=value + * @param value [CvPoint] Origin of the chain code + * @return [CvChain] self + */ +VALUE +rb_set_origin(VALUE self, VALUE origin) +{ + CVCHAIN(self)->origin = VALUE_TO_CVPOINT(origin); + return self; +} + +/* + * Returns the chain codes + * @overload codes + * @return [Array] Chain codes + * @opencv_func cvStartReadChainPoints + * @opencv_func CV_READ_SEQ_ELEM + */ +VALUE +rb_codes(VALUE self) +{ + CvChain *chain = CVCHAIN(self); + CvChainPtReader reader; + int total = chain->total; + VALUE ary = rb_ary_new2(total); + try { + cvStartReadChainPoints(chain, &reader); + for (int i = 0; i < total; ++i) { + CV_READ_SEQ_ELEM(reader.code, (*((CvSeqReader*)&(reader)))); + rb_ary_store(ary, i, INT2FIX(reader.code)); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return ary; +} + +/* + * Returns the points of the chain codes + * @overload points + * @return [Array] Points of the chain codes + * @opencv_func cvStartReadChainPoints + * @opencv_func CV_READ_CHAIN_POINT + */ +VALUE +rb_points(VALUE self) +{ + CvChain *chain = CVCHAIN(self); + CvChainPtReader reader; + CvPoint p = chain->origin; + int total = chain->total; + VALUE ary = rb_ary_new2(total); + try { + cvStartReadChainPoints(chain, &reader); + for (int i = 0; i < total; ++i) { + CV_READ_CHAIN_POINT(p, reader); + rb_ary_store(ary, i, cCvPoint::new_object(p)); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return ary; +} + +/* + * Approximates Freeman chains with a polygonal curve + * @overload approx_chain(options) + * @param options [Hash] Parameters + * @option options [Symbol] :method Approximation method (see the description of CvMat#find_contours) + * @option options [Number] :minimal_perimeter Approximates only those contours whose perimeters + * are not less than minimal_perimeter. Other chains are removed from the resulting structure. + * @option options [Boolean] :recursive Recursion flag. If it is true, the function approximates + * all chains that can be obtained from chain by using the h_next or v_next links. + * Otherwise, the single input chain is approximated. + * @return [CvSeq] Polygonal curve + * @opencv_func cvApproxChains + */ +VALUE +rb_approx_chains(int argc, VALUE *argv, VALUE self) +{ + VALUE approx_chain_option; + rb_scan_args(argc, argv, "01", &approx_chain_option); + + approx_chain_option = APPROX_CHAIN_OPTION(approx_chain_option); + VALUE storage = cCvMemStorage::new_object(); + CvSeq *seq = cvApproxChains(CVSEQ(self), CVMEMSTORAGE(storage), + APPROX_CHAIN_METHOD(approx_chain_option), + APPROX_CHAIN_PARAMETER(approx_chain_option), + APPROX_CHAIN_MINIMAL_PERIMETER(approx_chain_option), + APPROX_CHAIN_RECURSIVE(approx_chain_option)); + + if (seq && seq->total > 0) { + return cCvSeq::new_sequence(cCvChain::rb_class(), seq, cCvPoint::rb_class(), storage); + } + return Qnil; +} + +VALUE +new_object() +{ + VALUE storage = cCvMemStorage::new_object(); + CvSeq *seq = NULL; + try { + seq = cvCreateSeq(CV_SEQ_CHAIN_CONTOUR, sizeof(CvChain), sizeof(int), CVMEMSTORAGE(storage)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return cCvSeq::new_sequence(cCvChain::rb_class(), seq, T_FIXNUM, storage); +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); + VALUE cvseq = rb_define_class_under(opencv, "CvSeq"); + VALUE curve = rb_define_module_under(opencv, "Curve"); +#endif + + if (rb_klass) + return; + + VALUE opencv = rb_module_opencv(); + VALUE cvseq = cCvSeq::rb_class(); + VALUE curve = mCurve::rb_module(); + + rb_klass = rb_define_class_under(opencv, "CvChain", cvseq); + rb_include_module(rb_klass, curve); + VALUE approx_chain_option = rb_hash_new(); + rb_define_const(rb_klass, "APPROX_CHAIN_OPTION", approx_chain_option); + rb_hash_aset(approx_chain_option, ID2SYM(rb_intern("method")), ID2SYM(rb_intern("approx_simple"))); + rb_hash_aset(approx_chain_option, ID2SYM(rb_intern("parameter")), rb_float_new(0)); + rb_hash_aset(approx_chain_option, ID2SYM(rb_intern("minimal_perimeter")), INT2FIX(0)); + rb_hash_aset(approx_chain_option, ID2SYM(rb_intern("recursive")), Qfalse); + + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "origin", RUBY_METHOD_FUNC(rb_origin), 0); + rb_define_method(rb_klass, "origin=", RUBY_METHOD_FUNC(rb_set_origin), 1); + rb_define_method(rb_klass, "codes", RUBY_METHOD_FUNC(rb_codes), 0); + rb_define_method(rb_klass, "points", RUBY_METHOD_FUNC(rb_points), 0); + rb_define_method(rb_klass, "approx_chains", RUBY_METHOD_FUNC(rb_approx_chains), -1); + rb_define_alias(rb_klass, "approx", "approx_chains"); +} + +__NAMESPACE_END_CVCHAIN +__NAMESPACE_END_OPENCV diff --git a/ext/cvchain.h b/ext/opencv/cvchain.h similarity index 76% rename from ext/cvchain.h rename to ext/opencv/cvchain.h index fa06aabb..e0bb8923 100644 --- a/ext/cvchain.h +++ b/ext/opencv/cvchain.h @@ -11,7 +11,7 @@ #define RUBY_OPENCV_CVCHAIN_H #include "opencv.h" -#define __NAMESPACE_BEGIN_CVCHAIN namespace cCvChain{ +#define __NAMESPACE_BEGIN_CVCHAIN namespace cCvChain { #define __NAMESPACE_END_CVCHAIN } __NAMESPACE_BEGIN_OPENCV @@ -19,13 +19,16 @@ __NAMESPACE_BEGIN_CVCHAIN VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); +VALUE rb_allocate(VALUE klass); + +VALUE rb_initialize(int argc, VALUE *argv, VALUE self); VALUE rb_origin(VALUE self); VALUE rb_set_origin(VALUE self, VALUE origin); VALUE rb_codes(VALUE self); VALUE rb_points(VALUE self); -VALUE rb_approx_chain(int argc, VALUE *argv, VALUE self); +VALUE rb_approx_chains(int argc, VALUE *argv, VALUE self); VALUE new_object(); diff --git a/ext/cvcircle32f.cpp b/ext/opencv/cvcircle32f.cpp similarity index 54% rename from ext/cvcircle32f.cpp rename to ext/opencv/cvcircle32f.cpp index 4480e792..2e8bbe37 100644 --- a/ext/cvcircle32f.cpp +++ b/ext/opencv/cvcircle32f.cpp @@ -26,27 +26,6 @@ rb_class() return rb_klass; } -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - rb_klass = rb_define_class_under(opencv, "CvCircle32f", rb_cObject); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_method(rb_klass, "center", RUBY_METHOD_FUNC(rb_center), 0); - rb_define_method(rb_klass, "radius", RUBY_METHOD_FUNC(rb_radius), 0); - - //rb_define_method(rb_klass, "to_s", RUBY_METHOD_FUNC(rb_to_s), 0); - rb_define_method(rb_klass, "to_ary", RUBY_METHOD_FUNC(rb_to_ary), 0); -} - VALUE rb_allocate(VALUE klass) { @@ -55,7 +34,9 @@ rb_allocate(VALUE klass) } /* - * Return parameter on center. + * Returns center point of the circle + * @overload center + * @return [CvPoint2D32f] Center point of the circle */ VALUE rb_center(VALUE self) @@ -64,7 +45,9 @@ rb_center(VALUE self) } /* - * Return parameter on radius. + * Returns radius of the circle + * @overload radius + * @return [Number] Radius of the circle */ VALUE rb_radius(VALUE self) @@ -72,6 +55,37 @@ rb_radius(VALUE self) return rb_float_new(CVCIRCLE32F(self)->radius); } +/* + * Accesses to parameters of the circle by array-like interface ([X-coordinate, Y-coordinate, radius]) + * @overload [] + * @param index [Integer] Index + * @return [Number] X-coordinate, Y-coordinate or radius of the circle + */ +VALUE +rb_aref(VALUE self, VALUE index) +{ + switch (NUM2INT(index)) { + case 0: + return DBL2NUM(CVCIRCLE32F(self)->center.x); + break; + case 1: + return DBL2NUM(CVCIRCLE32F(self)->center.y); + break; + case 2: + return DBL2NUM(CVCIRCLE32F(self)->radius); + break; + default: + rb_raise(rb_eIndexError, "index should be 0...3"); + break; + } + return Qnil; +} + +/* + * Returns parameters of the circle as an array which contains [center, radius] + * @overload to_ary + * @return [Array] An array which contains [center, radius] + */ VALUE rb_to_ary(VALUE self) { @@ -86,5 +100,27 @@ new_object(CvCircle32f circle32f) return object; } +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + + VALUE opencv = rb_module_opencv(); + + rb_klass = rb_define_class_under(opencv, "CvCircle32f", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_method(rb_klass, "center", RUBY_METHOD_FUNC(rb_center), 0); + rb_define_method(rb_klass, "radius", RUBY_METHOD_FUNC(rb_radius), 0); + rb_define_method(rb_klass, "[]", RUBY_METHOD_FUNC(rb_aref), 1); + rb_define_method(rb_klass, "to_ary", RUBY_METHOD_FUNC(rb_to_ary), 0); + rb_define_alias(rb_klass, "to_a", "to_ary"); +} + __NAMESPACE_END_CVCIRCLE32F __NAMESPACE_END_OPENCV diff --git a/ext/cvcircle32f.h b/ext/opencv/cvcircle32f.h similarity index 85% rename from ext/cvcircle32f.h rename to ext/opencv/cvcircle32f.h index cccfa368..065c647b 100644 --- a/ext/cvcircle32f.h +++ b/ext/opencv/cvcircle32f.h @@ -12,12 +12,12 @@ #include "opencv.h" -#define __NAMESPACE_BEGIN_CVCIRCLE32F namespace cCvCircle32f{ +#define __NAMESPACE_BEGIN_CVCIRCLE32F namespace cCvCircle32f { #define __NAMESPACE_END_CVCIRCLE32F } __NAMESPACE_BEGIN_OPENCV -typedef struct CvCircle32f{ +typedef struct CvCircle32f { CvPoint2D32f center; float radius; } CvCircle32f; @@ -26,14 +26,13 @@ __NAMESPACE_BEGIN_CVCIRCLE32F VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_allocate(VALUE klass); VALUE rb_initialize(int argc, VALUE *argv, VALUE self); VALUE rb_center(VALUE self); VALUE rb_radius(VALUE self); - -VALUE rb_to_s(VALUE self); +VALUE rb_aref(VALUE self, VALUE index); VALUE rb_to_ary(VALUE self); VALUE new_object(CvCircle32f circle32f); diff --git a/ext/opencv/cvconnectedcomp.cpp b/ext/opencv/cvconnectedcomp.cpp new file mode 100644 index 00000000..fb103095 --- /dev/null +++ b/ext/opencv/cvconnectedcomp.cpp @@ -0,0 +1,156 @@ +/************************************************************ + + cvconnectedcomp.cpp - + + $Author: lsxi $ + + Copyright (C) 2005-2007 Masakazu Yonekura + +************************************************************/ +#include "cvconnectedcomp.h" +/* + * Document-class: OpenCV::CvConnectedComp + * + * Connected component + * see CvMat#flood_fill + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVCONNECTEDCOMP + +VALUE rb_klass; + +VALUE +rb_class() +{ + return rb_klass; +} + +VALUE +rb_allocate(VALUE klass) +{ + CvConnectedComp *ptr; + return Data_Make_Struct(klass, CvConnectedComp, 0, -1, ptr); +} + +/* + * Constructor + * @overload new(area = nil, value = nil, rect = nil, contour = nil) + * @param area [Number] Area of the segmented component + * @param value [CvScalar] Average color of the connected component + * @param rect [CvRect] ROI of the segmented component + * @param contour [CvSeq] Optional component boundary + * @return [CvConnectedComp] self + */ +VALUE +rb_initialize(int argc, VALUE *argv, VALUE self) +{ + VALUE area, value, rect, contour; + rb_scan_args(argc, argv, "04", &area, &value, &rect, &contour); + + if (!NIL_P(area)) + CVCONNECTEDCOMP(self)->area = NUM2DBL(area); + if (!NIL_P(value)) + CVCONNECTEDCOMP(self)->value = *CVSCALAR(value); + if (!NIL_P(rect)) + CVCONNECTEDCOMP(self)->rect = *CVRECT(rect); + if (!NIL_P(contour)) + CVCONNECTEDCOMP(self)->contour = CVSEQ(contour); + return self; +} + +/* + * Returns area of connected component + * @overload area + * @return [Number] Area of the connected component + */ +VALUE +rb_area(VALUE self) +{ + return rb_float_new(CVCONNECTEDCOMP(self)->area); +} + +/* + * Return average color of the connected component. + * @overload value + * @return [CvScalar] Average color of the connected component + */ +VALUE +rb_value(VALUE self) +{ + return REFER_OBJECT(cCvScalar::rb_class(), &CVCONNECTEDCOMP(self)->value, self); +} + +/* + * Return ROI of the segmented component + * @overload rect + * @return [CvRect] ROI of the segmented component + */ +VALUE +rb_rect(VALUE self) +{ + return REFER_OBJECT(cCvRect::rb_class(), &CVCONNECTEDCOMP(self)->rect, self); +} + +/* + * Set ROI of the segmented component + * @overload rect=value + * @param value [CvRect] ROI to set + * @return [CvRect] ROI of the segmented component + */ +VALUE +rb_set_rect(VALUE self, VALUE rect) +{ + CVCONNECTEDCOMP(self)->rect = VALUE_TO_CVRECT(rect); + return self; +} + +/* + * Returns optional component boundary + * @overload contour + * @return [CvContour] Optional component boundary + */ +VALUE +rb_contour(VALUE self) +{ + return REFER_OBJECT(cCvContour::rb_class(), &CVCONNECTEDCOMP(self)->contour, self); +} + +VALUE +new_object() +{ + return rb_allocate(rb_klass); +} + +VALUE +new_object(CvConnectedComp comp) +{ + VALUE object = rb_allocate(rb_klass); + *CVCONNECTEDCOMP(object) = comp; + return object; +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + + VALUE opencv = rb_module_opencv(); + + rb_klass = rb_define_class_under(opencv, "CvConnectedComp", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "area", RUBY_METHOD_FUNC(rb_area), 0); + rb_define_method(rb_klass, "value", RUBY_METHOD_FUNC(rb_value), 0); + rb_define_method(rb_klass, "rect", RUBY_METHOD_FUNC(rb_rect), 0); + rb_define_method(rb_klass, "rect=", RUBY_METHOD_FUNC(rb_set_rect), 1); + rb_define_method(rb_klass, "contour", RUBY_METHOD_FUNC(rb_contour), 0); +} + +__NAMESPACE_END_CVCONNECTEDCOMP +__NAMESPACE_END_OPENCV diff --git a/ext/cvconnectedcomp.h b/ext/opencv/cvconnectedcomp.h similarity index 86% rename from ext/cvconnectedcomp.h rename to ext/opencv/cvconnectedcomp.h index 8d11f763..beadd29e 100644 --- a/ext/cvconnectedcomp.h +++ b/ext/opencv/cvconnectedcomp.h @@ -12,7 +12,7 @@ #include "opencv.h" -#define __NAMESPACE_BEGIN_CVCONNECTEDCOMP namespace cCvConnectedComp{ +#define __NAMESPACE_BEGIN_CVCONNECTEDCOMP namespace cCvConnectedComp { #define __NAMESPACE_END_CVCONNECTEDCOMP } __NAMESPACE_BEGIN_OPENCV @@ -20,10 +20,11 @@ __NAMESPACE_BEGIN_CVCONNECTEDCOMP VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_allocate(VALUE klass); +VALUE rb_initialize(int argc, VALUE *argv, VALUE self); VALUE rb_area(VALUE self); VALUE rb_value(VALUE self); VALUE rb_rect(VALUE self); @@ -35,7 +36,9 @@ VALUE new_object(CvConnectedComp comp); __NAMESPACE_END_CVCONNECTEDCOMP -inline CvConnectedComp *CVCONNECTEDCOMP(VALUE object){ +inline CvConnectedComp* +CVCONNECTEDCOMP(VALUE object) +{ CvConnectedComp *ptr; Data_Get_Struct(object, CvConnectedComp, ptr); return ptr; diff --git a/ext/opencv/cvcontour.cpp b/ext/opencv/cvcontour.cpp new file mode 100644 index 00000000..f11f330d --- /dev/null +++ b/ext/opencv/cvcontour.cpp @@ -0,0 +1,384 @@ +/************************************************************ + + cvcontour.cpp - + + $Author: lsxi $ + + Copyright (C) 2007 Masakazu Yonekura + +************************************************************/ +#include "cvcontour.h" +/* + * Document-class: OpenCV::CvContour + * + * Contour + * + * @see CvMat#find_contours + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVCONTOUR + +#define APPROX_POLY_OPTION(op) rb_get_option_table(rb_klass, "APPROX_OPTION", op) +#define APPROX_POLY_METHOD(op) CVMETHOD("APPROX_POLY_METHOD", LOOKUP_HASH(op, "method"), CV_POLY_APPROX_DP) +#define APPROX_POLY_ACCURACY(op) NUM2DBL(LOOKUP_HASH(op, "accuracy")) +#define APPROX_POLY_RECURSIVE(op) TRUE_OR_FALSE(LOOKUP_HASH(op, "recursive")) + +VALUE rb_allocate(VALUE klass); +void cvcontour_free(void *ptr); + +VALUE rb_klass; + +VALUE +rb_class() +{ + return rb_klass; +} + +VALUE +rb_allocate(VALUE klass) +{ + return Data_Wrap_Struct(klass, mark_root_object, unregister_object, NULL); +} + +/* + * Constructor + * + * @overload new(seq_flags = CV_SEQ_ELTYPE_POINT | CV_SEQ_KIND_GENERIC, storage = nil) + * @param [Integer] seq_flags Flags of the created sequence, which are combinations of + * the element types and sequence types. + * - Element type: + * - CV_SEQ_ELTYPE_POINT: {CvPoint} + * - CV_32FC2: {CvPoint2D32f} + * - CV_SEQ_ELTYPE_POINT3D: {CvPoint3D32f} + * - CV_SEQ_ELTYPE_INDEX: Integer + * - CV_SEQ_ELTYPE_CODE: Integer (Freeman code) + * - Sequence type: + * - CV_SEQ_KIND_GENERIC: Generic sequence + * - CV_SEQ_KIND_CURVE: Curve + * @param [CvMemStorage] storage Sequence location + * @return [CvContour] self + * @opencv_func cvCreateSeq + * @example + * seq = CvContour.new(CV_SEQ_ELTYPE_POINT | CV_SEQ_KIND_CURVE) + * seq << CvPoint.new(1, 2) + * seq << 3 #=> TypeError + */ +VALUE +rb_initialize(int argc, VALUE *argv, VALUE self) +{ + VALUE seq_flags_value, storage_value; + rb_scan_args(argc, argv, "02", &seq_flags_value, &storage_value); + + int seq_flags = 0; + if (NIL_P(seq_flags_value)) { + seq_flags = CV_SEQ_ELTYPE_POINT | CV_SEQ_KIND_GENERIC; + } + else { + Check_Type(seq_flags_value, T_FIXNUM); + seq_flags = FIX2INT(seq_flags_value); + } + storage_value = CHECK_CVMEMSTORAGE(storage_value); + + try { + DATA_PTR(self) = (CvContour*)cCvSeq::create_seq(seq_flags, sizeof(CvContour), storage_value); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return self; +} + +/* + * Returns bounding box of the contour + * @overload rect + * @return [CvRect] Bounding box of the contour + */ +VALUE +rb_rect(VALUE self) +{ + return cCvRect::new_object(CVCONTOUR(self)->rect); +} + +/* + * Returns color of the contour + * @overload color + * @return [Number] Color of the contour + */ +VALUE +rb_color(VALUE self) +{ + return INT2NUM(CVCONTOUR(self)->color); +} + +/* + * Set color of the contour + * @overload color=value + * @param value [Number] Color of the contour + */ +VALUE +rb_set_color(VALUE self, VALUE color) +{ + CVCONTOUR(self)->color = NUM2INT(color); + return self; +} + +/* + * Returns reserved region values of the contour + * @overload reserved + * @return [Array] Reserved region values of the contour + */ +VALUE +rb_reserved(VALUE self) +{ + return rb_ary_new3(3, + INT2NUM(CVCONTOUR(self)->reserved[0]), + INT2NUM(CVCONTOUR(self)->reserved[1]), + INT2NUM(CVCONTOUR(self)->reserved[2])); +} + +/* + * Approximates polygonal curves with desired precision + * @overload approx_poly(options) + * @param options [Hash] Parameters + * @option options [Symbol] :method Approximation method (default :dp) + * * :dp - Douglas-Peucker algorithm. + * @option options [Number] :accuracy Parameter specifying the approximation accuracy. + * This is the maximum distance between the original curve and its approximation. + * @option options [Boolean] :recursive Recursion flag. If true, the function approximates + * all the contours accessible from curve by h_next and v_next links. + * @return [CvContour] Result of the approximation + * @return [nil] Approximation faied + * @opencv_func cvApproxPoly + */ +VALUE +rb_approx_poly(int argc, VALUE *argv, VALUE self) +{ + VALUE approx_poly_option; + rb_scan_args(argc, argv, "01", &approx_poly_option); + approx_poly_option = APPROX_POLY_OPTION(approx_poly_option); + VALUE storage = cCvMemStorage::new_object(); + CvSeq *contour = cvApproxPoly(CVCONTOUR(self), sizeof(CvContour), CVMEMSTORAGE(storage), + APPROX_POLY_METHOD(approx_poly_option), + APPROX_POLY_ACCURACY(approx_poly_option), + APPROX_POLY_RECURSIVE(approx_poly_option)); + + if (contour && contour->total > 0) { + return cCvSeq::new_sequence(cCvContour::rb_class(), contour, cCvPoint::rb_class(), storage); + } + return Qnil; +} + +/* + * Calculates up-right bounding rectangle of point set. + * @overload bounding_rect + * @return [CvRect] Bounding rectangle + * @opencv_func cvBoundingRect + */ +VALUE +rb_bounding_rect(VALUE self) +{ + CvRect rect; + try { + rect = cvBoundingRect(CVCONTOUR(self), 1); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return cCvRect::new_object(rect); +} + +/* + * Creates hierarchical representation of contour + * @overload create_tree(threshold = 0.0) + * @param threshold [Number] If <= 0, the method creates full binary tree representation. + * If > 0, the method creates representation with the precision threshold. + * @return [CvContourTree] Hierarchical representation of the contour + * @opencv_func cvCreateContourTree + */ +VALUE +rb_create_tree(int argc, VALUE *argv, VALUE self) +{ + VALUE threshold, storage; + rb_scan_args(argc, argv, "01", &threshold); + storage = cCvMemStorage::new_object(); + CvContourTree *tree = NULL; + try { + tree = cvCreateContourTree(CVSEQ(self), CVMEMSTORAGE(storage), IF_DBL(threshold, 0.0)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return cCvSeq::new_sequence(cCvContourTree::rb_class(), (CvSeq*)tree, cCvPoint::rb_class(), storage); +} + +/* + * Performs a point-in-contour test. + * The method determines whether the point is inside a contour, outside, + * or lies on an edge (or coincides with a vertex). + * @overload in?(point) + * @param point [CvPoint2D32f] Point tested against the contour + * @return [Boolean] If the point is inside, returns true. If outside, returns false. + * If lies on an edge, returns nil. + * @opencv_func cvPointPolygonTest + */ +VALUE +rb_in_q(VALUE self, VALUE point) +{ + double n = 0; + try { + n = cvPointPolygonTest(CVARR(self), VALUE_TO_CVPOINT2D32F(point), 0); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return n == 0 ? Qnil : n > 0 ? Qtrue : Qfalse; +} + +/* + * Calculates distance between a point and the nearest contour edgex + * @overload measure_distance(point) + * @param point [CvPoint2D32f] Point tested against the contour + * @return Signed distance between the point and the nearest contour edge + * @opencv_func cvPointPolygonTest + */ +VALUE +rb_measure_distance(VALUE self, VALUE point) +{ + double distance = 0; + try { + distance = cvPointPolygonTest(CVARR(self), VALUE_TO_CVPOINT2D32F(point), 1); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_float_new(distance); +} + +/* + * Determines whether the point is inside a contour, outside, or lies on an edge (or coinsides with a vertex). + * @overload point_polygon_test(point, measure_dist) + * @param point [CvPoint2D32f] Point tested against the contour + * @param measure_dist [Boolean] If true, the method estimates the signed distance from the point to + * the nearest contour edge. Otherwise, the function only checks if the point is inside a contour or not. + * @return [Number] When measure_dist = false, the return value is +1, -1 and 0, respectively. + * When measure_dist = true, it is a signed distance between the point and the nearest contour edge. + * @opencv_func cvPointPolygonTest + */ +VALUE +rb_point_polygon_test(VALUE self, VALUE point, VALUE measure_dist) +{ + int measure_dist_flag; + + if (measure_dist == Qtrue) + measure_dist_flag = 1; + else if (measure_dist == Qfalse) + measure_dist_flag = 0; + else + measure_dist_flag = NUM2INT(measure_dist); + + double dist = Qnil; + try { + dist = cvPointPolygonTest(CVARR(self), VALUE_TO_CVPOINT2D32F(point), measure_dist_flag); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + /* cvPointPolygonTest returns 100, -100 or 0 when measure_dist = 0 */ + if ((!measure_dist_flag) && ((int)dist) != 0) + dist = (dist > 0) ? 1 : -1; + + return rb_float_new(dist); +} + +/* + * call-seq: + * match_shapes(object, method) -> float + * + * Compares two shapes(self and object). object should be CvContour. + * + * A - object1, B - object2: + * * method=CV_CONTOURS_MATCH_I1 + * I1(A,B)=sumi=1..7abs(1/mAi - 1/mBi) + * * method=CV_CONTOURS_MATCH_I2 + * I2(A,B)=sumi=1..7abs(mAi - mBi) + * * method=CV_CONTOURS_MATCH_I3 + * I3(A,B)=sumi=1..7abs(mAi - mBi)/abs(mAi) + */ +VALUE +rb_match_shapes(int argc, VALUE *argv, VALUE self) +{ + VALUE object, method, param; + rb_scan_args(argc, argv, "21", &object, &method, ¶m); + int method_flag = CVMETHOD("COMPARISON_METHOD", method); + if (!rb_obj_is_kind_of(object, cCvContour::rb_class())) + rb_raise(rb_eTypeError, "argument 1 (shape) should be %s", + rb_class2name(cCvContour::rb_class())); + double result = 0; + try { + result = cvMatchShapes(CVARR(self), CVARR(object), method_flag); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_float_new(result); +} + +VALUE new_object() +{ + VALUE object = rb_allocate(rb_klass); + rb_initialize(0, NULL, object); + return object; +} + + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); + VALUE cvseq = rb_define_class_under(opencv, "CvSeq"); + VALUE curve = rb_define_module_under(opencv, "Curve"); + VALUE pointset = rb_define_module_under(opencv, "PointSet"); +#endif + + if (rb_klass) + return; + + VALUE opencv = rb_module_opencv(); + VALUE cvseq = cCvSeq::rb_class(); + VALUE curve = mCurve::rb_module(); + VALUE pointset = mPointSet::rb_module(); + + rb_klass = rb_define_class_under(opencv, "CvContour", cvseq); + rb_include_module(rb_klass, curve); + rb_include_module(rb_klass, pointset); + + rb_define_alloc_func(rb_klass, rb_allocate); + + VALUE approx_option = rb_hash_new(); + rb_define_const(rb_klass, "APPROX_OPTION", approx_option); + rb_hash_aset(approx_option, ID2SYM(rb_intern("method")), INT2FIX(CV_POLY_APPROX_DP)); + rb_hash_aset(approx_option, ID2SYM(rb_intern("accuracy")), rb_float_new(1.0)); + rb_hash_aset(approx_option, ID2SYM(rb_intern("recursive")), Qfalse); + + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "rect", RUBY_METHOD_FUNC(rb_rect), 0); + rb_define_method(rb_klass, "color", RUBY_METHOD_FUNC(rb_color), 0); + rb_define_method(rb_klass, "color=", RUBY_METHOD_FUNC(rb_set_color), 1); + rb_define_method(rb_klass, "reserved", RUBY_METHOD_FUNC(rb_reserved), 0); + rb_define_method(rb_klass, "approx_poly", RUBY_METHOD_FUNC(rb_approx_poly), -1); + rb_define_alias(rb_klass, "approx", "approx_poly"); + rb_define_method(rb_klass, "bounding_rect", RUBY_METHOD_FUNC(rb_bounding_rect), 0); + rb_define_method(rb_klass, "create_tree", RUBY_METHOD_FUNC(rb_create_tree), -1); + rb_define_method(rb_klass, "in?", RUBY_METHOD_FUNC(rb_in_q), 1); + rb_define_method(rb_klass, "measure_distance", RUBY_METHOD_FUNC(rb_measure_distance), 1); + rb_define_method(rb_klass, "point_polygon_test", RUBY_METHOD_FUNC(rb_point_polygon_test), 2); + rb_define_method(rb_klass, "match_shapes", RUBY_METHOD_FUNC(rb_match_shapes), -1); +} + +__NAMESPACE_END_CVCONTOUR +__NAMESPACE_END_OPENCV + diff --git a/ext/cvcontour.h b/ext/opencv/cvcontour.h similarity index 82% rename from ext/cvcontour.h rename to ext/opencv/cvcontour.h index 8eea828f..5cdc031b 100644 --- a/ext/cvcontour.h +++ b/ext/opencv/cvcontour.h @@ -11,7 +11,7 @@ #define RUBY_OPENCV_CVCONTOUR_H #include "opencv.h" -#define __NAMESPACE_BEGIN_CVCONTOUR namespace cCvContour{ +#define __NAMESPACE_BEGIN_CVCONTOUR namespace cCvContour { #define __NAMESPACE_END_CVCONTOUR } __NAMESPACE_BEGIN_OPENCV @@ -19,7 +19,7 @@ __NAMESPACE_BEGIN_CVCONTOUR VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_initialize(int argc, VALUE *argv, VALUE self); VALUE rb_rect(VALUE self); @@ -31,6 +31,10 @@ VALUE rb_bounding_rect(VALUE self); VALUE rb_create_tree(int argc, VALUE *argv, VALUE self); VALUE rb_in_q(VALUE self, VALUE point); VALUE rb_measure_distance(VALUE self, VALUE point); +VALUE rb_point_polygon_test(VALUE self, VALUE point, VALUE measure_dist); + +/* Matching*/ +VALUE rb_match_shapes(int argc, VALUE *argv, VALUE self); VALUE new_object(); __NAMESPACE_END_CVCONTOUR diff --git a/ext/cvcontourtree.cpp b/ext/opencv/cvcontourtree.cpp similarity index 54% rename from ext/cvcontourtree.cpp rename to ext/opencv/cvcontourtree.cpp index ccbfe4db..bb8b8334 100644 --- a/ext/cvcontourtree.cpp +++ b/ext/opencv/cvcontourtree.cpp @@ -11,15 +11,9 @@ /* * Document-class: OpenCV::CvContourTree * - * Contour tree. CvContour#create_tree + * Contour tree * - * C structure is here. - * typedef struct CvContourTree{ - * CV_SEQUENCE_FIELDS() - * CvPoint p1; - * CvPoint p2; - * }CvContourTree; - * + * @see CvContour#create_tree */ __NAMESPACE_BEGIN_OPENCV __NAMESPACE_BEGIN_CVCONTOURTREE @@ -32,33 +26,22 @@ rb_class() return rb_klass; } -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * cvseq = rb_define_class_under(opencv, "CvSeq"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - VALUE cvseq = cCvSeq::rb_class(); - - rb_klass = rb_define_class_under(opencv, "CvContourTree", cvseq); - rb_define_method(rb_klass, "p1", RUBY_METHOD_FUNC(rb_p1), 0); - rb_define_method(rb_klass, "p2", RUBY_METHOD_FUNC(rb_p2), 0); - rb_define_method(rb_klass, "contour", RUBY_METHOD_FUNC(rb_contour), 0); - -} - +/* + * Returns the first point of the binary tree root segment + * @overload p1 + * @return [CvPoint] First point of the binary tree root segment + */ VALUE rb_p1(VALUE self) { return REFER_OBJECT(cCvPoint::rb_class(), &CVCONTOURTREE(self)->p1, self); } +/* + * Returns the last point of the binary tree root segment + * @overload p2 + * @return [CvPoint] Last point of the binary tree root segment + */ VALUE rb_p2(VALUE self) { @@ -66,21 +49,48 @@ rb_p2(VALUE self) } /* - * call-seq: - * contour([criteria = 0]) -> cvcontour - * * Restores the contour from its binary tree representation. - * The parameter criteria determines the accuracy and/or the number of tree levels + * + * The parameter +criteria+ determines the accuracy and/or the number of tree levels * used for reconstruction, so it is possible to build approximated contour. + * @overload contour(criteria = 0) + * @param criteria [Integer] Criteria, where to stop reconstruction + * @return [CvContour] Contour tree + * @opencv_func cvContourFromContourTree */ VALUE -rb_contour(int argc, VALUE *argv, VALUE self) +rb_contour(VALUE self, VALUE criteria) { - VALUE criteria, storage; - rb_scan_args(argc, argv, "01", &criteria); - CvSeq *contour = cvContourFromContourTree(CVCONTOURTREE(self), CVMEMSTORAGE(storage), VALUE_TO_CVTERMCRITERIA(criteria)); + VALUE storage = cCvMemStorage::new_object(); + CvSeq *contour = NULL; + try { + contour = cvContourFromContourTree(CVCONTOURTREE(self), CVMEMSTORAGE(storage), + VALUE_TO_CVTERMCRITERIA(criteria)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } return cCvSeq::new_sequence(cCvContour::rb_class(), contour, cCvPoint::rb_class(), storage); } +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); + VALUE cvseq = rb_define_class_under(opencv, "CvSeq"); +#endif + if (rb_klass) + return; + VALUE opencv = rb_module_opencv(); + VALUE cvseq = cCvSeq::rb_class(); + + rb_klass = rb_define_class_under(opencv, "CvContourTree", cvseq); + rb_define_method(rb_klass, "p1", RUBY_METHOD_FUNC(rb_p1), 0); + rb_define_method(rb_klass, "p2", RUBY_METHOD_FUNC(rb_p2), 0); + rb_define_method(rb_klass, "contour", RUBY_METHOD_FUNC(rb_contour), 1); +} + __NAMESPACE_END_CVCONTOURTREE __NAMESPACE_END_OPENCV diff --git a/ext/cvcontourtree.h b/ext/opencv/cvcontourtree.h similarity index 90% rename from ext/cvcontourtree.h rename to ext/opencv/cvcontourtree.h index 1b2f9008..570fcde4 100644 --- a/ext/cvcontourtree.h +++ b/ext/opencv/cvcontourtree.h @@ -11,7 +11,7 @@ #define RUBY_OPENCV_CVCONTOURTREE_H #include "opencv.h" -#define __NAMESPACE_BEGIN_CVCONTOURTREE namespace cCvContourTree{ +#define __NAMESPACE_BEGIN_CVCONTOURTREE namespace cCvContourTree { #define __NAMESPACE_END_CVCONTOURTREE } __NAMESPACE_BEGIN_OPENCV @@ -19,11 +19,11 @@ __NAMESPACE_BEGIN_CVCONTOURTREE VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_p1(VALUE self); VALUE rb_p2(VALUE self); -VALUE rb_contour(int argc, VALUE *argv, VALUE self); +VALUE rb_contour(VALUE self, VALUE criteria); VALUE new_object(); diff --git a/ext/cvconvexitydefect.cpp b/ext/opencv/cvconvexitydefect.cpp similarity index 64% rename from ext/cvconvexitydefect.cpp rename to ext/opencv/cvconvexitydefect.cpp index 9c5c8f5f..e810e1a3 100644 --- a/ext/cvconvexitydefect.cpp +++ b/ext/opencv/cvconvexitydefect.cpp @@ -11,15 +11,7 @@ /* * Document-class: OpenCV::CvConvexityDefect * - * Convexity. - * C structure is here. - * typedef struct CvConvexityDefect { - * CvPoint* start; - * CvPoint* end; - * CvPoint* depth_point; - * float depth; - * }CvConvexityDefect; - * + * Convexity defect */ __NAMESPACE_BEGIN_OPENCV __NAMESPACE_BEGIN_CVCONVEXITYDEFECT @@ -32,30 +24,10 @@ rb_class() return rb_klass; } -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - rb_klass = rb_define_class_under(opencv, "CvConvexityDefect", rb_cObject); - rb_define_method(rb_klass, "start", RUBY_METHOD_FUNC(rb_start), 0); - rb_define_method(rb_klass, "end", RUBY_METHOD_FUNC(rb_end), 0); - rb_define_method(rb_klass, "depth_point", RUBY_METHOD_FUNC(rb_depth_point), 0); - rb_define_method(rb_klass, "depth", RUBY_METHOD_FUNC(rb_depth), 0); -} - /* - * call-seq: - * start -> cvpoint - * - * Return start point as CvPoint. + * Returns the point of the contour where the defect begins + * @overload start + * @return [CvPoint] Start point of the contour */ VALUE rb_start(VALUE self) @@ -64,10 +36,9 @@ rb_start(VALUE self) } /* - * call-seq: - * end -> cvpoint - * - * Return end point as CvPoint. + * Returns the point of the contour where the defect ends + * @overload end + * @return [CvPoint] End point of the contour */ VALUE rb_end(VALUE self) @@ -76,10 +47,9 @@ rb_end(VALUE self) } /* - * call-seq: - * depth_point -> cvpoint - * - * Return depth point as CvPoint. + * Returns the farthest from the convex hull point within the defect + * @overload depth_point + * @return [CvPoint] The farthest from the convex hull point within the defect */ VALUE rb_depth_point(VALUE self) @@ -88,10 +58,9 @@ rb_depth_point(VALUE self) } /* - * call-seq: - * depth -> float - * - * Return depth. + * Returns distance between the farthest point and the convex hull + * @overload depth + * @return [Number] Distance between the farthest point and the convex hull */ VALUE rb_depth(VALUE self) @@ -99,5 +68,25 @@ rb_depth(VALUE self) return rb_float_new(CVCONVEXITYDEFECT(self)->depth); } +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + + VALUE opencv = rb_module_opencv(); + + rb_klass = rb_define_class_under(opencv, "CvConvexityDefect", rb_cObject); + rb_define_method(rb_klass, "start", RUBY_METHOD_FUNC(rb_start), 0); + rb_define_method(rb_klass, "end", RUBY_METHOD_FUNC(rb_end), 0); + rb_define_method(rb_klass, "depth_point", RUBY_METHOD_FUNC(rb_depth_point), 0); + rb_define_method(rb_klass, "depth", RUBY_METHOD_FUNC(rb_depth), 0); +} + __NAMESPACE_END_CVCONVEXITYDEFECT __NAMESPACE_END_OPENCV diff --git a/ext/cvconvexitydefect.h b/ext/opencv/cvconvexitydefect.h similarity index 96% rename from ext/cvconvexitydefect.h rename to ext/opencv/cvconvexitydefect.h index be5c98a3..6c7df253 100644 --- a/ext/cvconvexitydefect.h +++ b/ext/opencv/cvconvexitydefect.h @@ -12,7 +12,7 @@ #include "opencv.h" -#define __NAMESPACE_BEGIN_CVCONVEXITYDEFECT namespace cCvConvexityDefect{ +#define __NAMESPACE_BEGIN_CVCONVEXITYDEFECT namespace cCvConvexityDefect { #define __NAMESPACE_END_CVCONVEXITYDEFECT } __NAMESPACE_BEGIN_OPENCV @@ -20,7 +20,7 @@ __NAMESPACE_BEGIN_CVCONVEXITYDEFECT VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_start(VALUE self); VALUE rb_end(VALUE self); diff --git a/ext/opencv/cverror.cpp b/ext/opencv/cverror.cpp new file mode 100644 index 00000000..8b1edb38 --- /dev/null +++ b/ext/opencv/cverror.cpp @@ -0,0 +1,115 @@ +/************************************************************ + + cverror.cpp - + + $Author: lsxi $ + + Copyright (C) 2005-2006 Masakazu Yonekura + +************************************************************/ +#include "cverror.h" +/* + * Document-class: OpenCV::CvError + * + * OpenCV errors + */ + +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVERROR + +st_table *cv_error = st_init_numtable(); + +VALUE rb_klass; + +void +REGISTER_CVERROR(const char* object_name, int error_code) +{ + st_insert(cv_error, (st_data_t)error_code, + (st_data_t)rb_define_class_under(rb_module_opencv(), object_name, rb_klass)); +} + +VALUE +rb_class() +{ + return rb_klass; +} + +VALUE +by_code(int error_code) +{ + VALUE klass = 0; + st_lookup(cv_error, (st_data_t)error_code, (st_data_t*)&klass); + return klass ? klass : rb_eStandardError; +} + +void +raise(cv::Exception e) +{ + rb_raise(by_code(e.code), "%s", e.what()); +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + + VALUE opencv = rb_module_opencv(); + rb_klass = rb_define_class_under(opencv, "CvError", rb_eStandardError); + REGISTER_CVERROR("CvStsBackTrace", CV_StsBackTrace); + REGISTER_CVERROR("CvStsError", CV_StsError); + REGISTER_CVERROR("CvStsInternal", CV_StsInternal); + REGISTER_CVERROR("CvStsNoMem", CV_StsNoMem); + REGISTER_CVERROR("CvStsBadArg", CV_StsBadArg); + REGISTER_CVERROR("CvStsBadFunc", CV_StsBadFunc); + REGISTER_CVERROR("CvStsNoConv", CV_StsNoConv); + REGISTER_CVERROR("CvStsAutoTrace", CV_StsAutoTrace); + REGISTER_CVERROR("CvHeaderIsNull", CV_HeaderIsNull); + REGISTER_CVERROR("CvBadImageSize", CV_BadImageSize); + REGISTER_CVERROR("CvBadOffset", CV_BadOffset); + REGISTER_CVERROR("CvBadDataPtr", CV_BadDataPtr); + REGISTER_CVERROR("CvBadStep", CV_BadStep); + REGISTER_CVERROR("CvBadModelOrChSeq", CV_BadModelOrChSeq); + REGISTER_CVERROR("CvBadNumChannels", CV_BadNumChannels); + REGISTER_CVERROR("CvBadNumChannel1U", CV_BadNumChannel1U); + REGISTER_CVERROR("CvBadDepth", CV_BadDepth); + REGISTER_CVERROR("CvBadAlphaChannel", CV_BadAlphaChannel); + REGISTER_CVERROR("CvBadOrder", CV_BadOrder); + REGISTER_CVERROR("CvBadOrigin", CV_BadOrigin); + REGISTER_CVERROR("CvBadAlign", CV_BadAlign); + REGISTER_CVERROR("CvBadCallBack", CV_BadCallBack); + REGISTER_CVERROR("CvBadTileSize", CV_BadTileSize); + REGISTER_CVERROR("CvBadCOI", CV_BadCOI); + REGISTER_CVERROR("CvBadROISize", CV_BadROISize); + REGISTER_CVERROR("CvMaskIsTiled", CV_MaskIsTiled); + REGISTER_CVERROR("CvStsNullPtr", CV_StsNullPtr); + REGISTER_CVERROR("CvStsVecLengthErr", CV_StsVecLengthErr); + REGISTER_CVERROR("CvStsFilterStructContentErr", CV_StsFilterStructContentErr); + REGISTER_CVERROR("CvStsKernelStructContentErr", CV_StsKernelStructContentErr); + REGISTER_CVERROR("CvStsFilterOffsetErr", CV_StsFilterOffsetErr); + REGISTER_CVERROR("CvStsBadSize", CV_StsBadSize); + REGISTER_CVERROR("CvStsDivByZero", CV_StsDivByZero); + REGISTER_CVERROR("CvStsInplaceNotSupported", CV_StsInplaceNotSupported); + REGISTER_CVERROR("CvStsObjectNotFound", CV_StsObjectNotFound); + REGISTER_CVERROR("CvStsUnmatchedFormats", CV_StsUnmatchedFormats); + REGISTER_CVERROR("CvStsBadFlag", CV_StsBadFlag); + REGISTER_CVERROR("CvStsBadPoint", CV_StsBadPoint); + REGISTER_CVERROR("CvStsBadMask", CV_StsBadMask); + REGISTER_CVERROR("CvStsUnmatchedSizes", CV_StsUnmatchedSizes); + REGISTER_CVERROR("CvStsUnsupportedFormat", CV_StsUnsupportedFormat); + REGISTER_CVERROR("CvStsOutOfRange", CV_StsOutOfRange); + REGISTER_CVERROR("CvStsParseError", CV_StsParseError); + REGISTER_CVERROR("CvStsNotImplemented", CV_StsNotImplemented); + REGISTER_CVERROR("CvStsBadMemBlock", CV_StsBadMemBlock); + REGISTER_CVERROR("CvStsAssert", CV_StsAssert); + REGISTER_CVERROR("CvGpuNotSupported", CV_GpuNotSupported); + REGISTER_CVERROR("CvGpuApiCallError", CV_GpuApiCallError); +} + +__NAMESPACE_END_CVERROR +__NAMESPACE_END_OPENCV diff --git a/ext/opencv/cverror.h b/ext/opencv/cverror.h new file mode 100644 index 00000000..aba2cf89 --- /dev/null +++ b/ext/opencv/cverror.h @@ -0,0 +1,28 @@ +/************************************************************ + + cverror.h - + + $Author: lsxi $ + + Copyright (C) 2005-2006 Masakazu Yonekura + +************************************************************/ +#ifndef RUBY_OPENCV_CVERROR_H +#define RUBY_OPENCV_CVERROR_H + +#include "opencv.h" + +#define __NAMESPACE_BEGIN_CVERROR namespace cCvError { +#define __NAMESPACE_END_CVERROR } + +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVERROR + +void init_ruby_class(); +VALUE by_code(int error_code); +void raise(cv::Exception e); + +__NAMESPACE_END_CVERROR +__NAMESPACE_END_OPENCV + +#endif // RUBY_OPENCV_CVERROR_H diff --git a/ext/opencv/cvfeaturetree.cpp b/ext/opencv/cvfeaturetree.cpp new file mode 100644 index 00000000..a559e8ba --- /dev/null +++ b/ext/opencv/cvfeaturetree.cpp @@ -0,0 +1,123 @@ +/************************************************************ + + cvfeaturetree.cpp - + + $Author: ser1zw $ + + Copyright (C) 2011 ser1zw + +************************************************************/ +#include "cvfeaturetree.h" +/* + * Document-class: OpenCV::CvFeatureTree + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVFEATURETREE + +VALUE rb_klass; + +VALUE +rb_class() +{ + return rb_klass; +} + +void +mark_feature_tree(void *ptr) +{ + if (ptr) { + VALUE desc = ((CvFeatureTreeWrap*)ptr)->desc; + rb_gc_mark(desc); + } +} + +void +rb_release_feature_tree(void *ptr) +{ + if (ptr) { + CvFeatureTree* ft = ((CvFeatureTreeWrap*)ptr)->feature_tree; + cvReleaseFeatureTree(ft); + } +} + +VALUE +rb_allocate(VALUE klass) +{ + CvFeatureTreeWrap* ptr; + return Data_Make_Struct(klass, CvFeatureTreeWrap, mark_feature_tree, + rb_release_feature_tree, ptr); +} + +/* + * Create a new kd-tree + * @overload new(desc) + * @param desc [CvMat] Descriptors + * @return [CvFeatureTree] self + * @opencv_func cvCreateKDTree + */ +VALUE +rb_initialize(VALUE self, VALUE desc) +{ + CvMat* desc_mat = CVMAT_WITH_CHECK(desc); + CvFeatureTreeWrap* self_ptr = (CvFeatureTreeWrap*)DATA_PTR(self); + free(self_ptr); + self_ptr = ALLOC(CvFeatureTreeWrap); + try { + self_ptr->feature_tree = cvCreateKDTree(desc_mat); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + self_ptr->desc = desc; + return self; +} + +/* + * Find features from kd-tree + * @overload find_features(desc, k, emax) + * @param desc [CvMat] m x d matrix of (row-)vectors to find the nearest neighbors of. + * @param k [Integer] The number of neighbors to find. + * @param emax [Integer] The maximum number of leaves to visit. + * @return [Array] Array of [results, dist] + * - results: m x k set of row indices of matching vectors (referring to matrix passed to cvCreateFeatureTree). Contains -1 in some columns if fewer than k neighbors found. + * - dist: m x k matrix of distances to k nearest neighbors. + * @opencv_func cvFindFeatures + */ +VALUE +rb_find_features(VALUE self, VALUE desc, VALUE k, VALUE emax) +{ + CvMat* desc_mat = CVMAT_WITH_CHECK(desc); + int _k = NUM2INT(k); + VALUE results = cCvMat::new_object(desc_mat->rows, _k, CV_32SC1); + VALUE dist = cCvMat::new_object(desc_mat->rows, _k, CV_64FC1); + try { + cvFindFeatures(CVFEATURETREE(self), desc_mat, CVMAT(results), CVMAT(dist), _k, NUM2INT(emax)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_assoc_new(results, dist); +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + + VALUE opencv = rb_module_opencv(); + rb_klass = rb_define_class_under(opencv, "CvFeatureTree", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), 1); + + rb_define_method(rb_klass, "find_features", RUBY_METHOD_FUNC(rb_find_features), 3); +} + +__NAMESPACE_END_OPENCV +__NAMESPACE_END_CVFEATURETREE + diff --git a/ext/opencv/cvfeaturetree.h b/ext/opencv/cvfeaturetree.h new file mode 100644 index 00000000..9ddd0124 --- /dev/null +++ b/ext/opencv/cvfeaturetree.h @@ -0,0 +1,55 @@ +/************************************************************ + + cvfeaturetree.h - + + $Author: ser1zw $ + + Copyright (C) 2011 ser1zw + +************************************************************/ +#ifndef RUBY_OPENCV_CVFEATURETREE_H +#define RUBY_OPENCV_CVFEATURETREE_H + +#include "opencv.h" + +#define __NAMESPACE_BEGIN_CVFEATURETREE namespace cCvFeatureTree { +#define __NAMESPACE_END_CVFEATURETREE } + +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVFEATURETREE + +VALUE rb_class(); +void init_ruby_class(); +VALUE rb_allocate(VALUE klass); +VALUE rb_initialize(VALUE self, VALUE desc); +VALUE rb_find_features(VALUE self, VALUE desc, VALUE k, VALUE emax); + +__NAMESPACE_END_CVFEATURETREE + +typedef struct _CvFeatureTreeWrap { + CvFeatureTree* feature_tree; + VALUE desc; +} CvFeatureTreeWrap; + +inline CvFeatureTree* +CVFEATURETREE(VALUE object) +{ + CvFeatureTreeWrap* ptr; + Data_Get_Struct(object, CvFeatureTreeWrap, ptr); + return ptr->feature_tree; +} + +inline CvFeatureTree* +CVFEATURETREE_WITH_CHECK(VALUE object) +{ + if (!rb_obj_is_kind_of(object, cCvFeatureTree::rb_class())) + raise_typeerror(object, cCvFeatureTree::rb_class()); + return CVFEATURETREE(object); +} + +__NAMESPACE_END_OPENCV + +#endif // RUBY_OPENCV_CVFEATURETREE + + + diff --git a/ext/opencv/cvfont.cpp b/ext/opencv/cvfont.cpp new file mode 100644 index 00000000..37ea75ce --- /dev/null +++ b/ext/opencv/cvfont.cpp @@ -0,0 +1,228 @@ +/************************************************************ + + cvfont.cpp - + + $Author: lsxi $ + + Copyright (C) 2005-2006 Masakazu Yonekura + +************************************************************/ +#include "cvfont.h" +/* + * Document-class: OpenCV::CvFont + * + * Font structure that can be passed to text rendering functions. + * see CvMat#put_text, CvMat#put_text! + */ + +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVFONT + +VALUE rb_klass; + +int +rb_font_option_line_type(VALUE font_option) +{ + VALUE line_type = LOOKUP_HASH(font_option, "line_type"); + if (FIXNUM_P(line_type)) { + return FIX2INT(line_type); + } + else if (line_type == ID2SYM(rb_intern("aa"))) { + return CV_AA; + } + return 0; +} + +VALUE +rb_class() +{ + return rb_klass; +} + +VALUE +rb_allocate(VALUE klass) +{ + CvFont *ptr; + return Data_Make_Struct(klass, CvFont, 0, -1, ptr); +} + +/* + * Create font object + * @overload new(face, font_option = nil) + * @param face [Symbol] Font name identifier. Only a subset of Hershey fonts (http://sources.isc.org/utils/misc/hershey-font.txt) are supported now: + * - :simplex - normal size sans-serif font + * - :plain - small size sans-serif font + * - :duplex - normal size sans-serif font (more complex than :simplex) + * - :complex - normal size serif font + * - :triplex - normal size serif font (more complex than :complex) + * - :complex_small - smaller version of :complex + * - :script_simplex - hand-writing style font + * - :script_complex - more complex variant of :script_simplex + * + * @param font_option [Hash] should be Hash include these keys. + * @option font_option [Number] :hscale Horizontal scale. If equal to 1.0, the characters have the original width depending on the font type. If equal to 0.5, the characters are of half the original width. + * @option font_option [Number] :vscale Vertical scale. If equal to 1.0, the characters have the original height depending on the font type. If equal to 0.5, the characters are of half the original height. + * @option font_option [Number] :shear Approximate tangent of the character slope relative to the vertical line. Zero value means a non-italic font, 1.0f means ~45 degree slope, etc. + * @option font_option [Number] :thickness Thickness of the text strokes. + * @option font_option [Number] :line_type Type of the strokes, see CvMat#Line description. + * @option font_option [Number] :italic If value is not nil or false that means italic or oblique font. + * + * @example Create Font + * OpenCV::CvFont.new(:simplex, :hscale => 2, :vslace => 2, :italic => true) + * # create 2x bigger than normal, italic type font. + * + * @opencv_func cvInitFont + */ +VALUE +rb_initialize(int argc, VALUE *argv, VALUE self) +{ + VALUE face, font_option; + rb_scan_args(argc, argv, "11", &face, &font_option); + Check_Type(face, T_SYMBOL); + face = rb_hash_lookup(rb_const_get(cCvFont::rb_class(), rb_intern("FACE")), face); + if (NIL_P(face)) { + rb_raise(rb_eArgError, "undefined face."); + } + font_option = FONT_OPTION(font_option); + + int font_face = NUM2INT(face); + if (FO_ITALIC(font_option)) { + font_face |= CV_FONT_ITALIC; + } + try { + cvInitFont(CVFONT(self), + font_face, + FO_HSCALE(font_option), + FO_VSCALE(font_option), + FO_SHEAR(font_option), + FO_THICKNESS(font_option), + FO_LINE_TYPE(font_option)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return self; +} + +/* + * Returns font face + * @overload face + * @return [Integer] Font face + */ +VALUE +rb_face(VALUE self) +{ + return INT2FIX(CVFONT(self)->font_face); +} + +/* + * Returns hscale + * @overload hscale + * @return [Number] hscale + */ +VALUE +rb_hscale(VALUE self) +{ + return rb_float_new(CVFONT(self)->hscale); +} + +/* + * Returns vscale + * @overload vscale + * @return [Number] vscale + */ +VALUE +rb_vscale(VALUE self) +{ + return rb_float_new(CVFONT(self)->vscale); +} + +/* + * Returns shear + * @overload shear + * @return [Number] shear + */ +VALUE +rb_shear(VALUE self) +{ + return rb_float_new(CVFONT(self)->shear); +} + +/* + * Returns thickness + * @overload thickness + * @return [Integer] thickness + */ +VALUE +rb_thickness(VALUE self) +{ + return INT2FIX(CVFONT(self)->thickness); +} + +/* + * Returns line type + * @overload line_type + * @return [Integer] line_type + */ +VALUE +rb_line_type(VALUE self) +{ + return INT2FIX(CVFONT(self)->line_type); +} + +/* + * Returns italic or not + * @overload italic + * @return [Boolean] self is italic or not + */ +VALUE +rb_italic(VALUE self) +{ + return ((CVFONT(self)->font_face & CV_FONT_ITALIC) > 0) ? Qtrue : Qfalse; +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + + VALUE opencv = rb_module_opencv(); + rb_klass = rb_define_class_under(opencv, "CvFont", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + VALUE face = rb_hash_new(); + rb_define_const(rb_klass, "FACE", face); + rb_hash_aset(face, ID2SYM(rb_intern("simplex")), INT2FIX(CV_FONT_HERSHEY_SIMPLEX)); + rb_hash_aset(face, ID2SYM(rb_intern("plain")), INT2FIX(CV_FONT_HERSHEY_PLAIN)); + rb_hash_aset(face, ID2SYM(rb_intern("duplex")), INT2FIX(CV_FONT_HERSHEY_DUPLEX)); + rb_hash_aset(face, ID2SYM(rb_intern("triplex")), INT2FIX(CV_FONT_HERSHEY_TRIPLEX)); + rb_hash_aset(face, ID2SYM(rb_intern("complex_small")), INT2FIX(CV_FONT_HERSHEY_COMPLEX_SMALL)); + rb_hash_aset(face, ID2SYM(rb_intern("script_simplex")), INT2FIX(CV_FONT_HERSHEY_SCRIPT_SIMPLEX)); + rb_hash_aset(face, ID2SYM(rb_intern("script_complex")), INT2FIX(CV_FONT_HERSHEY_SCRIPT_COMPLEX)); + + VALUE default_option = rb_hash_new(); + rb_define_const(rb_klass, "FONT_OPTION", default_option); + rb_hash_aset(default_option, ID2SYM(rb_intern("hscale")), rb_float_new(1.0)); + rb_hash_aset(default_option, ID2SYM(rb_intern("vscale")), rb_float_new(1.0)); + rb_hash_aset(default_option, ID2SYM(rb_intern("shear")), INT2FIX(0)); + rb_hash_aset(default_option, ID2SYM(rb_intern("thickness")), INT2FIX(1)); + rb_hash_aset(default_option, ID2SYM(rb_intern("line_type")), INT2FIX(8)); + + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "face", RUBY_METHOD_FUNC(rb_face), 0); + rb_define_method(rb_klass, "hscale", RUBY_METHOD_FUNC(rb_hscale), 0); + rb_define_method(rb_klass, "vscale", RUBY_METHOD_FUNC(rb_vscale), 0); + rb_define_method(rb_klass, "shear", RUBY_METHOD_FUNC(rb_shear), 0); + rb_define_method(rb_klass, "thickness", RUBY_METHOD_FUNC(rb_thickness), 0); + rb_define_method(rb_klass, "line_type", RUBY_METHOD_FUNC(rb_line_type), 0); + rb_define_method(rb_klass, "italic", RUBY_METHOD_FUNC(rb_italic), 0); +} + +__NAMESPACE_END_CVFONT +__NAMESPACE_END_OPENCV diff --git a/ext/opencv/cvfont.h b/ext/opencv/cvfont.h new file mode 100644 index 00000000..f2083030 --- /dev/null +++ b/ext/opencv/cvfont.h @@ -0,0 +1,64 @@ +/************************************************************ + + cvfont.h - + + $Author: lsxi $ + + Copyright (C) 2005-2006 Masakazu Yonekura + +************************************************************/ +#ifndef RUBY_OPENCV_CVFONT_H +#define RUBY_OPENCV_CVFONT_H + +#include "opencv.h" + +#define __NAMESPACE_BEGIN_CVFONT namespace cCvFont { +#define __NAMESPACE_END_CVFONT } + +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVFONT + +#define FONT_OPTION(op) rb_get_option_table(rb_klass, "FONT_OPTION", op) +#define FO_ITALIC(op) TRUE_OR_FALSE(LOOKUP_HASH(op, "italic")) +#define FO_HSCALE(op) NUM2DBL(LOOKUP_HASH(op, "hscale")) +#define FO_VSCALE(op) NUM2DBL(LOOKUP_HASH(op, "vscale")) +#define FO_SHEAR(op) NUM2DBL(LOOKUP_HASH(op, "shear")) +#define FO_THICKNESS(op) NUM2INT(LOOKUP_HASH(op, "thickness")) +#define FO_LINE_TYPE(op) rb_font_option_line_type(op) + +VALUE rb_class(); + +void init_ruby_class(); + +VALUE rb_allocate(VALUE klass); +VALUE rb_initialize(int argc, VALUE *argv, VALUE self); + +VALUE rb_face(VALUE self); +VALUE rb_hscale(VALUE self); +VALUE rb_vscale(VALUE self); +VALUE rb_shear(VALUE self); +VALUE rb_thickness(VALUE self); +VALUE rb_line_type(VALUE self); +VALUE rb_italic(VALUE self); + +__NAMESPACE_END_CVFONT + +inline CvFont* +CVFONT(VALUE object) +{ + CvFont *ptr; + Data_Get_Struct(object, CvFont, ptr); + return ptr; +} + +inline CvFont* +CVFONT_WITH_CHECK(VALUE object) +{ + if (!rb_obj_is_kind_of(object, cCvFont::rb_class())) + raise_typeerror(object, cCvFont::rb_class()); + return CVFONT(object); +} + +__NAMESPACE_END_OPENCV + +#endif // RUBY_OPENCV_CVFONT_H diff --git a/ext/opencv/cvhaarclassifiercascade.cpp b/ext/opencv/cvhaarclassifiercascade.cpp new file mode 100644 index 00000000..4a007b69 --- /dev/null +++ b/ext/opencv/cvhaarclassifiercascade.cpp @@ -0,0 +1,148 @@ +/************************************************************ + + cvhaarclassifercascade.cpp - + + $Author: lsxi $ + + Copyright (C) 2005-2007 Masakazu Yonekura + +************************************************************/ +#include "cvhaarclassifiercascade.h" +/* + * Document-class: OpenCV::CvHaarClassifierCascade + * + * Haar Feature-based Cascade Classifier for Object Detection + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVHAARCLASSIFERCASCADE + +VALUE rb_klass; + +VALUE +rb_class() +{ + return rb_klass; +} + +VALUE +rb_allocate(VALUE klass) +{ + return OPENCV_OBJECT(klass, 0); +} + +void +cvhaarclassifiercascade_free(void* ptr) +{ + if (ptr) { + CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)ptr; + cvReleaseHaarClassifierCascade(&cascade); + } +} + +/* + * Load trained cascade of haar classifers from file. + * + * @overload load(filename) + * @param filename [String] Haar classifer file name + * @return [CvHaarClassifierCascade] Object detector + * @scope class + * @opencv_func cvLoad + */ +VALUE +rb_load(VALUE klass, VALUE path) +{ + CvHaarClassifierCascade *cascade = NULL; + try { + cascade = (CvHaarClassifierCascade*)cvLoad(StringValueCStr(path), 0, 0, 0); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + if (!CV_IS_HAAR_CLASSIFIER(cascade)) + rb_raise(rb_eArgError, "invalid format haar classifier cascade file."); + return Data_Wrap_Struct(klass, 0, cvhaarclassifiercascade_free, cascade); +} + +/* + * Detects objects of different sizes in the input image. + * + * @overload detect_objects(image, options = nil) + * @param image [CvMat,IplImage] Matrix of the type CV_8U containing an image where objects are detected. + * @param options [Hash] Options + * @option options [Number] :scale_factor + * Parameter specifying how much the image size is reduced at each image scale. + * @option options [Number] :storage + * Memory storage to store the resultant sequence of the object candidate rectangles + * @option options [Number] :min_neighbors + * Parameter specifying how many neighbors each candidate rectangle should have to retain it. + * @option options [CvSize] :min_size + * Minimum possible object size. Objects smaller than that are ignored. + * @option options [CvSize] :max_size + * Maximum possible object size. Objects larger than that are ignored. + * @return [CvSeq] Detected objects as a list of rectangles + * @opencv_func cvHaarDetectObjects + */ +VALUE +rb_detect_objects(int argc, VALUE *argv, VALUE self) +{ + VALUE image, options; + rb_scan_args(argc, argv, "11", &image, &options); + + double scale_factor; + int flags, min_neighbors; + CvSize min_size, max_size; + VALUE storage_val; + if (NIL_P(options)) { + scale_factor = 1.1; + flags = 0; + min_neighbors = 3; + min_size = max_size = cvSize(0, 0); + storage_val = cCvMemStorage::new_object(); + } + else { + scale_factor = IF_DBL(LOOKUP_HASH(options, "scale_factor"), 1.1); + flags = IF_INT(LOOKUP_HASH(options, "flags"), 0); + min_neighbors = IF_INT(LOOKUP_HASH(options, "min_neighbors"), 3); + VALUE min_size_val = LOOKUP_HASH(options, "min_size"); + min_size = NIL_P(min_size_val) ? cvSize(0, 0) : VALUE_TO_CVSIZE(min_size_val); + VALUE max_size_val = LOOKUP_HASH(options, "max_size"); + max_size = NIL_P(max_size_val) ? cvSize(0, 0) : VALUE_TO_CVSIZE(max_size_val); + storage_val = CHECK_CVMEMSTORAGE(LOOKUP_HASH(options, "storage")); + } + + VALUE result = Qnil; + try { + CvSeq *seq = cvHaarDetectObjects(CVARR_WITH_CHECK(image), CVHAARCLASSIFIERCASCADE(self), CVMEMSTORAGE(storage_val), + scale_factor, min_neighbors, flags, min_size, max_size); + result = cCvSeq::new_sequence(cCvSeq::rb_class(), seq, cCvAvgComp::rb_class(), storage_val); + if (rb_block_given_p()) { + for(int i = 0; i < seq->total; ++i) + rb_yield(REFER_OBJECT(cCvAvgComp::rb_class(), cvGetSeqElem(seq, i), storage_val)); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return result; +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + + VALUE opencv = rb_module_opencv(); + rb_klass = rb_define_class_under(opencv, "CvHaarClassifierCascade", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_singleton_method(rb_klass, "load", RUBY_METHOD_FUNC(rb_load), 1); + rb_define_method(rb_klass, "detect_objects", RUBY_METHOD_FUNC(rb_detect_objects), -1); +} + +__NAMESPACE_END_CVHAARCLASSIFERCASCADE +__NAMESPACE_END_OPENCV diff --git a/ext/cvhaarclassifiercascade.h b/ext/opencv/cvhaarclassifiercascade.h similarity index 73% rename from ext/cvhaarclassifiercascade.h rename to ext/opencv/cvhaarclassifiercascade.h index c0fce6c2..17e504c9 100644 --- a/ext/cvhaarclassifiercascade.h +++ b/ext/opencv/cvhaarclassifiercascade.h @@ -10,28 +10,26 @@ #ifndef RUBY_OPENCV_CVHAARCLASSIFIERCASCADE_H #define RUBY_OPENCV_CVHAARCLASSIFIERCASCADE_H -#define __NAMESPACE_BEGIN_CVHAARCLASSIFERCASCADE namespace cCvHaarClassifierCascade{ +#define __NAMESPACE_BEGIN_CVHAARCLASSIFERCASCADE namespace cCvHaarClassifierCascade { #define __NAMESPACE_END_CVHAARCLASSIFERCASCADE } -#include"opencv.h" +#include "opencv.h" __NAMESPACE_BEGIN_OPENCV __NAMESPACE_BEGIN_CVHAARCLASSIFERCASCADE VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_allocate(VALUE klass); -VALUE rb_initialize(int argc, VALUE *argv, VALUE self); VALUE rb_load(VALUE klass, VALUE path); -VALUE rb_save(VALUE self, VALUE name); VALUE rb_detect_objects(int argc, VALUE *argv, VALUE self); -VALUE rb_detect_objects_with_pruning(int argc, VALUE *argv, VALUE self); __NAMESPACE_END_CVHAARCLASSIFERCASCADE -inline CvHaarClassifierCascade *CVHAARCLASSIFIERCASCADE(VALUE object){ +inline CvHaarClassifierCascade* +CVHAARCLASSIFIERCASCADE(VALUE object) { CvHaarClassifierCascade *ptr; Data_Get_Struct(object, CvHaarClassifierCascade, ptr); return ptr; diff --git a/ext/opencv/cvhistogram.cpp b/ext/opencv/cvhistogram.cpp new file mode 100644 index 00000000..dce84399 --- /dev/null +++ b/ext/opencv/cvhistogram.cpp @@ -0,0 +1,717 @@ +/************************************************************ + + cvhistogram.cpp - + + $Author: lsxi $ + + Copyright (C) 2005-2008 Masakazu Yonekura + +************************************************************/ +#include "cvhistogram.h" +/* + * Document-class: OpenCV::CvHistogram + * + * Multi-dimensional histogram. + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVHISTOGRAM + +VALUE rb_klass; + +VALUE +rb_class() +{ + return rb_klass; +} + +void +release_hist(void* ptr) +{ + if (ptr) { + try { + cvReleaseHist((CvHistogram**)&ptr); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + } +} + +VALUE +rb_allocate(VALUE klass) +{ + CvHistogram* ptr = NULL; + return Data_Wrap_Struct(klass, 0, release_hist, ptr); +} + +float* +ary2fltptr(VALUE ary, float* buff) +{ + Check_Type(ary, T_ARRAY); + int size = RARRAY_LEN(ary); + VALUE* ary_ptr = RARRAY_PTR(ary); + for (int i = 0; i < size; ++i) { + buff[i] = NUM2DBL(ary_ptr[i]); + } + return buff; +} + +int* +ary2intptr(VALUE ary, int* buff) +{ + Check_Type(ary, T_ARRAY); + int size = RARRAY_LEN(ary); + VALUE* ary_ptr = RARRAY_PTR(ary); + for (int i = 0; i < size; ++i) { + buff[i] = NUM2INT(ary_ptr[i]); + } + return buff; +} + +/* + * Creates a histogram + * @overload new(dims, sizes, type, ranges=nil, uniform=true) + * @param dims [Integer] Number of histogram dimensions + * @param sizes [Array] Array of the histogram dimension sizes + * @param type [Integer] + * Histogram representation format. CV_HIST_ARRAY means that the histogram data is represented + * as a multi-dimensional dense array CvMatND. CV_HIST_SPARSE means that histogram data is + * represented as a multi-dimensional sparse array CvSparseMat. + * @param ranges [Array] + * Array of ranges for the histogram bins. Its meaning depends on the uniform parameter value. + * The ranges are used when the histogram is calculated or backprojected to determine which + * histogram bin corresponds to which value/tuple of values from the input image(s). + * @param uniform [Boolean] Uniformity flag. + * @return [CvHistogram] Histogram + * @opencv_func cvCreateHist + */ +VALUE +rb_initialize(int argc, VALUE *argv, VALUE self) +{ + VALUE _dims, _sizes, _type, _ranges, _uniform; + int uniform; + int* sizes; + float** ranges = NULL; + + rb_scan_args(argc, argv, "32", &_dims, &_sizes, &_type, &_ranges, &_uniform); + int sizes_len = RARRAY_LEN(_sizes); + sizes = RB_ALLOC_N(int, sizes_len); + + if (NIL_P(_ranges)) { + sizes = ary2intptr(_sizes, sizes); + ranges = NULL; + } + else { + ranges = RB_ALLOC_N(float*, sizes_len); + VALUE* range_ptr = RARRAY_PTR(_ranges); + int i; + for (i = 0; i < sizes_len; i++) { + sizes[i] = NUM2INT(RARRAY_PTR(_sizes)[i]); + ranges[i] = ary2fltptr(range_ptr[i], RB_ALLOC_N(float, 2)); + } + } + uniform = TRUE_OR_FALSE(_uniform, 1); + + try { + DATA_PTR(self) = cvCreateHist(NUM2INT(_dims), sizes, NUM2INT(_type), ranges, uniform); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return self; +} + +/* + * Returns self is uniform histogram or not + * @overload is_uniform? + * @return [Boolean] Uniform or not + * @opencv_func CV_IS_UNIFORM_HIST + */ +VALUE +rb_is_uniform(VALUE self) +{ + return CV_IS_UNIFORM_HIST(CVHISTOGRAM(self)) ? Qtrue : Qfalse; +} + +/* + * Returns self is sparse histogram or not + * @overload is_sparse? + * @return [Boolean] Sparse or not + * @opencv_func CV_IS_SPARSE_HIST + */ +VALUE +rb_is_sparse(VALUE self) +{ + return CV_IS_SPARSE_HIST(CVHISTOGRAM(self)) ? Qtrue : Qfalse; +} + +/* + * Returns self has range or not + * @overload has_range? + * @return [Boolean] Has range or not + * @opencv_func CV_HIST_HAS_RANGES +*/ +VALUE +rb_has_range(VALUE self) +{ + return CV_HIST_HAS_RANGES(CVHISTOGRAM(self)) ? Qtrue : Qfalse; +} + +/* + * Calculates a histogram of a set of arrays. + * @overload calc_hist(images, accumulate=nil, mask=nil) + * @param images [Array] + * Source arrays. They all should have the same depth, CV_8U or CV_32F, and the same size. + * Each of them can have an arbitrary number of channels. + * @param accumulate [Boolean] + * Accumulation flag. If it is set, the histogram is not cleared in the beginning when it is allocated. + * This feature enables you to compute a single histogram from several sets of arrays, + * or to update the histogram in time. + * @param mask [CvMat] + * Optional mask. If the matrix is not empty, it must be an 8-bit array of the same size as images[i]. + * The non-zero mask elements mark the array elements counted in the histogram. + * @return [CvHistogram] Histogram of a set of arrays + * @opencv_func cvCalcHist + */ +VALUE +rb_calc_hist(int argc, VALUE* argv, VALUE self) +{ + return rb_calc_hist_bang(argc, argv, rb_copy_hist(self)); +} + +/* + * Calculates a histogram of a set of arrays. + * @overload calc_hist!(images, accumulate=nil, mask=nil) + * @see #calc_hist + * @opencv_func cvCalcHist + */ +VALUE +rb_calc_hist_bang(int argc, VALUE* argv, VALUE self) +{ + VALUE images, accumulate, mask; + rb_scan_args(argc, argv, "12", &images, &accumulate, &mask); + Check_Type(images, T_ARRAY); + int num_images = RARRAY_LEN(images); + if (num_images == 0) { + rb_raise(rb_eArgError, "One or more arrays are required."); + } + IplImage** img = RB_ALLOC_N(IplImage*, num_images); + VALUE* images_ptr = RARRAY_PTR(images); + for (int i = 0; i < num_images; i++) { + img[i] = IPLIMAGE_WITH_CHECK(images_ptr[i]); + } + CvMat* m = NIL_P(mask) ? NULL : CVMAT_WITH_CHECK(mask); + try { + cvCalcHist(img, CVHISTOGRAM(self), TRUE_OR_FALSE(accumulate, 0), m); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Queries the value of the histogram bin. + * @overload [](idx0) + * @overload [](idx0, idx1) + * @overload [](idx0, idx1, idx2) + * @overload [](idx0, idx1, idx2, idx3, ...) + * @param idx* [Integer] *-th index + * @return [Number] The value of the specified bin of the 1D, 2D, 3D, or N-D histogram. + * @opencv_func cvQueryHistValue_1D + * @opencv_func cvQueryHistValue_2D + * @opencv_func cvQueryHistValue_3D + * @opencv_func cvQueryHistValue_nD + */ +VALUE +rb_aref(VALUE self, VALUE args) +{ + int num_idx = RARRAY_LEN(args); + int* idx = RB_ALLOC_N(int, num_idx); + VALUE* args_ptr = RARRAY_PTR(args); + for (int i = 0; i < num_idx; i++) { + idx[i] = NUM2INT(args_ptr[i]); + } + + float value = 0.0; + CvHistogram* self_ptr = CVHISTOGRAM(self); + try { + switch (num_idx) { + case 1: + value = cvQueryHistValue_1D(self_ptr, idx[0]); + break; + case 2: + value = cvQueryHistValue_2D(self_ptr, idx[0], idx[1]); + break; + case 3: + value = cvQueryHistValue_3D(self_ptr, idx[0], idx[1], idx[2]); + break; + default: + value = cvQueryHistValue_nD(self_ptr, idx); + break; + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return rb_float_new((double)value); +} + +/* + * Finds the minimum and maximum histogram bins. + * @overload min_max_value + * @return [Array] + * [min_value, max_value, min_idx, max_idx]: Array of the minimum / maximum value of the histogram + * and their coordinates. + * - min_value: The minimum value of the histogram. + * - max_value: The maximum value of the histogram. + * - min_idx: The array of coordinates for the minimum. + * - max_idx: The array of coordinates for the maximum. + * @opencv_func cvGetMinMaxHistValue + */ +VALUE +rb_min_max_value(VALUE self) +{ + CvHistogram* self_ptr = CVHISTOGRAM(self); + int dims = 0; + float min_value = 0.0, max_value = 0.0; + int *min_idx = NULL; + int *max_idx = NULL; + try { + dims = cvGetDims(self_ptr->bins, NULL); + min_idx = RB_ALLOC_N(int, dims); + max_idx = RB_ALLOC_N(int, dims); + cvGetMinMaxHistValue(CVHISTOGRAM(self), &min_value, &max_value, min_idx, max_idx); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + VALUE _min_idx = rb_ary_new2(dims); + VALUE _max_idx = rb_ary_new2(dims); + for (int i = 0; i < dims; i++) { + rb_ary_store(_min_idx, i, INT2NUM(min_idx[i])); + rb_ary_store(_max_idx, i, INT2NUM(max_idx[i])); + } + + return rb_ary_new3(4, rb_float_new((double)min_value), rb_float_new((double)max_value), + _min_idx, _max_idx); +} + +/* + * Returns number of array dimensions + * @overload [](idx0, idx1, ...) + * @param idx* [Integer] *-th index + * @return [Array>] + * [dims, sizes]: Number of array dimensions and its sizes. + * - dims (Integer): Number of array dimensions + * - sizes (Array): Vector of the array dimension sizes. + * For 2D arrays the number of rows (height) goes first, + * number of columns (width) next. + * @opencv_func cvGetDims + */ +VALUE +rb_dims(VALUE self) +{ + VALUE _sizes = Qnil; + int size[CV_MAX_DIM]; + int dims = 0; + try { + dims = cvGetDims(CVHISTOGRAM(self)->bins, size); + _sizes = rb_ary_new2(dims); + for (int i = 0; i < dims; ++i) { + rb_ary_store(_sizes, i, INT2NUM(size[i])); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_assoc_new(INT2NUM(dims), _sizes); +} + +/* + * Clones histogram + * @overload copy_hist + * @return [CvHistogram] Copy of the histogram + * @opencv_func cvCopyHist + */ +VALUE +rb_copy_hist(VALUE self) +{ + CvHistogram* hist = NULL; + try { + cvCopyHist(CVHISTOGRAM(self), &hist); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return Data_Wrap_Struct(rb_klass, 0, release_hist, hist); +} + +/* + * Sets all histogram bins to 0 in case of dense histogram + * and removes all histogram bins in case of sparse array. + * @overload clear_hist + * @return [CvHistogram] Cleared histogram + * @opencv_func cvClearHist + */ +VALUE +rb_clear_hist(VALUE self) +{ + return rb_clear_hist_bang(rb_copy_hist(self)); +} + +/* + * Sets all histogram bins to 0 in case of dense histogram + * and removes all histogram bins in case of sparse array. + * This method changes self. + * @overload clear_hist! + * @see #clear_hist + * @return [CvHistogram] Cleared histogram + * @opencv_func cvClearHist + */ +VALUE +rb_clear_hist_bang(VALUE self) +{ + try { + cvClearHist(CVHISTOGRAM(self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Returns normalized the histogram bins by scaling them, + * such that the sum of the bins becomes equal to factor. + * @overload normalize(factor) + * @param factor [Number] Normalization factor. The sum of the bins becomes equal to this value. + * @return [CvHistogram] Normalized histogram + * @opencv_func cvNormalizeHist + */ +VALUE +rb_normalize_hist(VALUE self, VALUE factor) +{ + return rb_normalize_hist_bang(rb_copy_hist(self), factor); +} + +/* + * Returns normalized the histogram bins by scaling them, + * such that the sum of the bins becomes equal to factor. + * This method changes self. + * @overload normalize!(factor) + * @param factor [Number] Normalization factor. The sum of the bins becomes equal to this value. + * @return [CvHistogram] Normalized histogram + * @see #normalize + * @opencv_func cvNormalizeHist + */ +VALUE +rb_normalize_hist_bang(VALUE self, VALUE factor) +{ + try { + cvNormalizeHist(CVHISTOGRAM(self), NUM2DBL(factor)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Returns cleared histogram bins that are below the specified threshold. + * @overload thresh_hist(threshold) + * @param threshold [Number] Threshold value + * @return [CvHistogram] Cleared histogram + * @opencv_func cvThreshHist + */ +VALUE +rb_thresh_hist(VALUE self, VALUE threshold) +{ + return rb_thresh_hist_bang(rb_copy_hist(self), threshold); +} + +/* + * Cleares histogram bins that are below the specified threshold. + * This method changes self. + * @overload thresh_hist!(threshold) + * @param threshold [Number] Threshold value + * @return [CvHistogram] Cleared histogram + * @see #thresh_hist + * @opencv_func cvThreshHist + */ +VALUE +rb_thresh_hist_bang(VALUE self, VALUE threshold) +{ + try { + cvThreshHist(CVHISTOGRAM(self), NUM2DBL(threshold)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Sets the bounds of the histogram bins. + * @overload set_hist_bin_ranges(ranges, uniform=true) + * @param ranges [Array] + * Array of ranges for the histogram bins. Its meaning depends on the uniform parameter value. + * The ranges are used when the histogram is calculated or backprojected to determine + * which histogram bin corresponds to which value/tuple of values from the input image(s). + * @param uniform [Boolean] + * Uniformity flag. + * @return [CvHistogram] + * Histogram + * @opencv_func cvSetHistBinRanges + */ +VALUE +rb_set_hist_bin_ranges(int argc, VALUE* argv, VALUE self) +{ + return rb_set_hist_bin_ranges_bang(argc, argv, rb_copy_hist(self)); +} + +/* + * Sets the bounds of the histogram bins. This method changes self. + * @overload set_hist_bin_ranges!(ranges, uniform=true) + * @param ranges [Array] + * Array of ranges for the histogram bins. Its meaning depends on the uniform parameter value. + * The ranges are used when the histogram is calculated or backprojected to determine + * which histogram bin corresponds to which value/tuple of values from the input image(s). + * @param uniform [Boolean] + * Uniformity flag. + * @return [CvHistogram] + * Histogram + * @see #set_hist_bin_ranges + * @opencv_func cvSetHistBinRanges + */ +VALUE +rb_set_hist_bin_ranges_bang(int argc, VALUE* argv, VALUE self) +{ + VALUE _ranges, _uniform; + rb_scan_args(argc, argv, "11", &_ranges, &_uniform); + Check_Type(_ranges, T_ARRAY); + + int ranges_size = RARRAY_LEN(_ranges); + float** ranges = RB_ALLOC_N(float*, ranges_size); + VALUE* range_ptr = RARRAY_PTR(_ranges); + for (int i = 0; i < ranges_size; ++i) { + ranges[i] = ary2fltptr(range_ptr[i], RB_ALLOC_N(float, 2)); + } + int uniform = TRUE_OR_FALSE(_uniform, 1); + + try { + cvSetHistBinRanges(CVHISTOGRAM(self), ranges, uniform); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return self; +} + +/* + * Calculates the back projection of a histogram. + * @overload calc_back_project(images) + * @param images [Array] + * Source arrays. They all should have the same depth, CV_8U or CV_32F, and the same size. + * Each of them can have an arbitrary number of channels. + * @return [CvMat,IplImage] + * Destination back projection array that is a single-channel array of the same size and depth + * as the first element of images + * @opencv_func cvCalcBackProject + */ +VALUE +rb_calc_back_project(VALUE self, VALUE image) +{ + Check_Type(image, T_ARRAY); + int num_images = RARRAY_LEN(image); + if (num_images == 0) { + return Qnil; + } + + IplImage** img = RB_ALLOC_N(IplImage*, num_images); + VALUE* image_ptr = RARRAY_PTR(image); + for (int i = 0; i < num_images; ++i) { + img[i] = IPLIMAGE_WITH_CHECK(image_ptr[i]); + } + + CvSize size; + size.width = img[0]->width; + size.height = img[0]->height; + VALUE back_project = cCvMat::new_mat_kind_object(size, image_ptr[0]); + try { + cvCalcBackProject(img, CVARR(back_project), CVHISTOGRAM(self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return back_project; +} + +/* + * Locates a template within an image by using a histogram comparison. + * @overload calc_back_project_patch(images, patch_size, method, factor) + * @param images [Array] Source arrays. + * @param pach_size [CvSize] Size of the patch slid though the source image. + * @param method [Integer] + * Comparison method that could be one of the following: + * - CV_COMP_CORREL: Correlation + * - CV_COMP_CHISQR: Chi-Square + * - CV_COMP_INTERSECT: Intersection + * - CV_COMP_BHATTACHARYYA: Bhattacharyya distance + * - CV_COMP_HELLINGER: Synonym for CV_COMP_BHATTACHARYYA + * @param factor [Number] + * Normalization factor for histograms that affects the normalization scale + * of the destination image. Pass 1 if not sure. + * @return [CvMat,IplImage] Destination image. + * @opencv_func cvCalcBackProject + */ +VALUE +rb_calc_back_project_patch(VALUE self, VALUE image, VALUE patch_size, VALUE method, VALUE factor) +{ + Check_Type(image, T_ARRAY); + int num_images = RARRAY_LEN(image); + if (num_images == 0) { + return Qnil; + } + + IplImage** img = RB_ALLOC_N(IplImage*, num_images); + VALUE* image_ptr = RARRAY_PTR(image); + for (int i = 0; i < num_images; ++i) { + img[i] = IPLIMAGE_WITH_CHECK(image_ptr[i]); + } + + CvSize patchsize = VALUE_TO_CVSIZE(patch_size); + CvSize dst_size; + dst_size.width = img[0]->width - patchsize.width + 1; + dst_size.height = img[0]->height - patchsize.height + 1; + + VALUE dst = cCvMat::new_mat_kind_object(dst_size, image_ptr[0], CV_32F, 1); + try { + cvCalcBackProjectPatch(img, CVARR(dst), patchsize, CVHISTOGRAM(self), + NUM2INT(method), NUM2DBL(factor)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return dst; +} + +/* + * Compares two histograms. + * @overload compare_hist(hist1, hist2, method) + * @param hist1 [CvHistogram] First compared histogram. + * @param hist2 [CvHistogram] Second compared histogram of the same size as hist1. + * @param method [Integer] + * Comparison method that could be one of the following: + * - CV_COMP_CORREL: Correlation + * - CV_COMP_CHISQR: Chi-Square + * - CV_COMP_INTERSECT: Intersection + * - CV_COMP_BHATTACHARYYA: Bhattacharyya distance + * - CV_COMP_HELLINGER: Synonym for CV_COMP_BHATTACHARYYA + * @return [Number] Distance of the two histograms. + * @scope class + * @opencv_func cvCompareHist + */ +VALUE +rb_compare_hist(VALUE self, VALUE hist1, VALUE hist2, VALUE method) +{ + double result = 0; + try { + result = cvCompareHist(CVHISTOGRAM_WITH_CHECK(hist1), CVHISTOGRAM_WITH_CHECK(hist2), + NUM2INT(method)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return rb_float_new(result); +} + +/* + * Divides one histogram by another. + * @overload calc_prob_density(hist1, hist2, scale=255) + * @param hist1 [CvHistogram] First histogram (the divisor). + * @param hist2 [CvHistogram] Second histogram. + * @param scale [Number] Scale factor for the destination histogram. + * @return [CvHistogram] Destination histogram. + * @opencv_func cvCalcProbDensity + */ +VALUE +rb_calc_prob_density(int argc, VALUE* argv, VALUE self) +{ + VALUE hist1, hist2, scale; + rb_scan_args(argc, argv, "21", &hist1, &hist2, &scale); + double s = NIL_P(scale) ? 255 : NUM2DBL(scale); + + CvHistogram* hist1_ptr = CVHISTOGRAM_WITH_CHECK(hist1); + VALUE dst_hist = rb_allocate(rb_klass); + try { + cvCopyHist(hist1_ptr, (CvHistogram**)&(DATA_PTR(dst_hist))); + cvCalcProbDensity(hist1_ptr, CVHISTOGRAM_WITH_CHECK(hist2), CVHISTOGRAM(dst_hist), s); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return dst_hist; +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + + VALUE opencv = rb_module_opencv(); + rb_klass = rb_define_class_under(opencv, "CvHistogram", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "is_uniform?", RUBY_METHOD_FUNC(rb_is_uniform), 0); + rb_define_method(rb_klass, "is_sparse?", RUBY_METHOD_FUNC(rb_is_sparse), 0); + rb_define_method(rb_klass, "has_range?", RUBY_METHOD_FUNC(rb_has_range), 0); + rb_define_method(rb_klass, "dims", RUBY_METHOD_FUNC(rb_dims), 0); + rb_define_method(rb_klass, "calc_hist", RUBY_METHOD_FUNC(rb_calc_hist), -1); + rb_define_method(rb_klass, "calc_hist!", RUBY_METHOD_FUNC(rb_calc_hist_bang), -1); + rb_define_method(rb_klass, "[]", RUBY_METHOD_FUNC(rb_aref), -2); + rb_define_alias(rb_klass, "query_hist_value", "[]"); + rb_define_method(rb_klass, "min_max_value", RUBY_METHOD_FUNC(rb_min_max_value), 0); + rb_define_method(rb_klass, "copy_hist", RUBY_METHOD_FUNC(rb_copy_hist), 0); + + rb_define_method(rb_klass, "clear_hist", RUBY_METHOD_FUNC(rb_clear_hist), 0); + rb_define_alias(rb_klass, "clear", "clear_hist"); + rb_define_method(rb_klass, "clear_hist!", RUBY_METHOD_FUNC(rb_clear_hist_bang), 0); + rb_define_alias(rb_klass, "clear!", "clear_hist!"); + + rb_define_method(rb_klass, "normalize_hist", RUBY_METHOD_FUNC(rb_normalize_hist), 1); + rb_define_alias(rb_klass, "normalize", "normalize_hist"); + rb_define_method(rb_klass, "normalize_hist!", RUBY_METHOD_FUNC(rb_normalize_hist_bang), 1); + rb_define_alias(rb_klass, "normalize!", "normalize_hist!"); + + rb_define_method(rb_klass, "thresh_hist", RUBY_METHOD_FUNC(rb_thresh_hist), 1); + rb_define_alias(rb_klass, "thresh", "thresh_hist"); + rb_define_method(rb_klass, "thresh_hist!", RUBY_METHOD_FUNC(rb_thresh_hist_bang), 1); + rb_define_alias(rb_klass, "thresh!", "thresh_hist!"); + + rb_define_method(rb_klass, "set_hist_bin_ranges", RUBY_METHOD_FUNC(rb_set_hist_bin_ranges), -1); + rb_define_method(rb_klass, "set_hist_bin_ranges!", RUBY_METHOD_FUNC(rb_set_hist_bin_ranges_bang), -1); + + rb_define_method(rb_klass, "calc_back_project", RUBY_METHOD_FUNC(rb_calc_back_project), 1); + rb_define_method(rb_klass, "calc_back_project_patch", RUBY_METHOD_FUNC(rb_calc_back_project_patch), 4); + + rb_define_singleton_method(rb_klass, "calc_prob_density", RUBY_METHOD_FUNC(rb_calc_prob_density), -1); + rb_define_singleton_method(rb_klass, "compare_hist", RUBY_METHOD_FUNC(rb_compare_hist), 3); +} + +__NAMESPACE_END_CVHISTOGRAM +__NAMESPACE_END_OPENCV diff --git a/ext/opencv/cvhistogram.h b/ext/opencv/cvhistogram.h new file mode 100644 index 00000000..2ef3ad58 --- /dev/null +++ b/ext/opencv/cvhistogram.h @@ -0,0 +1,73 @@ +/************************************************************ + + cvhistogram.h - + + $Author: lsxi $ + + Copyright (C) 2005-2008 Masakazu Yonekura + +************************************************************/ +#ifndef RUBY_OPENCV_CVHISTOGRAM_H +#define RUBY_OPENCV_CVHISTOGRAM_H + +#include "opencv.h" + +#define __NAMESPACE_BEGIN_CVHISTOGRAM namespace cCvHistogram { +#define __NAMESPACE_END_CVHISTOGRAM } + +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVHISTOGRAM + +VALUE rb_class(); +VALUE rb_allocate(VALUE klass); +void init_ruby_class(); + +VALUE rb_initialize(int argc, VALUE *argv, VALUE self); +VALUE rb_is_uniform(VALUE self); +VALUE rb_is_sparse(VALUE self); +VALUE rb_has_range(VALUE self); +VALUE rb_calc_hist(int argc, VALUE* argv, VALUE self); +VALUE rb_calc_hist_bang(int argc, VALUE* argv, VALUE self); +VALUE rb_aref(VALUE self, VALUE args); +VALUE rb_min_max_value(VALUE self); +VALUE rb_dims(VALUE self); +VALUE rb_copy_hist(VALUE self); + +VALUE rb_clear_hist(VALUE self); +VALUE rb_clear_hist_bang(VALUE self); + +VALUE rb_normalize_hist(VALUE self, VALUE factor); +VALUE rb_normalize_hist_bang(VALUE self, VALUE factor); +VALUE rb_thresh_hist(VALUE self, VALUE threshold); +VALUE rb_thresh_hist_bang(VALUE self, VALUE threshold); + +VALUE rb_set_hist_bin_ranges(int argc, VALUE* argv, VALUE self); +VALUE rb_set_hist_bin_ranges_bang(int argc, VALUE* argv, VALUE self); + +VALUE rb_calc_back_project(VALUE self, VALUE image); +VALUE rb_calc_back_project_patch(VALUE self, VALUE image, VALUE patch_size, VALUE method, VALUE factor); + +VALUE rb_compare_hist(VALUE self, VALUE hist1, VALUE hist2, VALUE method); +VALUE rb_calc_prob_density(int argc, VALUE* argv, VALUE self); + +__NAMESPACE_END_CVHISTOGRAM + +inline CvHistogram* +CVHISTOGRAM(VALUE object) +{ + CvHistogram* ptr; + Data_Get_Struct(object, CvHistogram, ptr); + return ptr; +} + +inline CvHistogram* +CVHISTOGRAM_WITH_CHECK(VALUE object) +{ + if (!rb_obj_is_kind_of(object, cCvHistogram::rb_class())) + raise_typeerror(object, cCvHistogram::rb_class()); + return CVHISTOGRAM(object); +} + +__NAMESPACE_END_OPENCV + +#endif // RUBY_OPENCV_CVHISTOGRAM_H diff --git a/ext/opencv/cvhumoments.cpp b/ext/opencv/cvhumoments.cpp new file mode 100644 index 00000000..1930c8bc --- /dev/null +++ b/ext/opencv/cvhumoments.cpp @@ -0,0 +1,178 @@ +/************************************************************ + + cvhumoments.cpp - + + $Author: ser1zw $ + + Copyright (C) 2011 ser1zw + +************************************************************/ +#include "cvhumoments.h" + +/* + * Document-class: OpenCV::CvHuMoments + * + * Hu invariants + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVHUMOMENTS + +VALUE rb_klass; + +VALUE +rb_class() +{ + return rb_klass; +} + +VALUE +rb_allocate(VALUE klass) +{ + CvHuMoments *ptr; + return Data_Make_Struct(klass, CvHuMoments, 0, -1, ptr); +} + +/* + * Calculates the seven Hu invariants + * @overload new(src_moments) + * @param src_moments [CvMoment] Input moments + * @return [CvHuMoments] Output Hu invariants + * @opencv_func cvGetHuMoments + * @see http://en.wikipedia.org/wiki/Image_moment#Rotation_invariant_moments + */ +VALUE +rb_initialize(VALUE self, VALUE src_moments) +{ + try { + cvGetHuMoments(CVMOMENTS(src_moments), CVHUMOMENTS(self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Returns hu1 invariant + * @overload hu1 + * @return [Number] hu1 invariant + */ +VALUE rb_hu1(VALUE self) { + return DBL2NUM(CVHUMOMENTS(self)->hu1); +} + +/* + * Returns hu2 invariant + * @overload hu2 + * @return [Number] hu2 invariant + */ +VALUE rb_hu2(VALUE self) { + return DBL2NUM(CVHUMOMENTS(self)->hu2); +} + +/* + * Returns hu3 invariant + * @overload hu3 + * @return [Number] hu3 invariant + */ +VALUE rb_hu3(VALUE self) { + return DBL2NUM(CVHUMOMENTS(self)->hu3); +} + +/* + * Returns hu4 invariant + * @overload hu4 + * @return [Number] hu4 invariant + */ +VALUE rb_hu4(VALUE self) { + return DBL2NUM(CVHUMOMENTS(self)->hu4); +} + +/* + * Returns hu5 invariant + * @overload hu5 + * @return [Number] hu5 invariant + */ +VALUE rb_hu5(VALUE self) { + return DBL2NUM(CVHUMOMENTS(self)->hu5); +} + +/* + * Returns hu6 invariant + * @overload hu6 + * @return [Number] hu6 invariant + */ +VALUE rb_hu6(VALUE self) { + return DBL2NUM(CVHUMOMENTS(self)->hu6); +} + +/* + * Returns hu7 invariant + * @overload hu7 + * @return [Number] hu7 invariant + */ +VALUE rb_hu7(VALUE self) { + return DBL2NUM(CVHUMOMENTS(self)->hu7); +} + +/* + * Returns hu invaliants as an Array + * @overload to_ary + * @return [Array] Hu invaliants + */ +VALUE +rb_to_ary(VALUE self) +{ + CvHuMoments *hu_moments = CVHUMOMENTS(self); + return rb_ary_new3(7, + rb_float_new(hu_moments->hu1), + rb_float_new(hu_moments->hu2), + rb_float_new(hu_moments->hu3), + rb_float_new(hu_moments->hu4), + rb_float_new(hu_moments->hu5), + rb_float_new(hu_moments->hu6), + rb_float_new(hu_moments->hu7)); +} + +VALUE +new_object(CvMoments *src_moments) +{ + VALUE object = rb_allocate(rb_klass); + try { + cvGetHuMoments(src_moments, CVHUMOMENTS(object)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return object; +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + VALUE opencv = rb_module_opencv(); + + rb_klass = rb_define_class_under(opencv, "CvHuMoments", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), 1); + rb_define_method(rb_klass, "to_ary", RUBY_METHOD_FUNC(rb_to_ary), 0); + rb_define_alias(rb_klass, "to_a", "to_ary"); + + rb_define_method(rb_klass, "hu1", RUBY_METHOD_FUNC(rb_hu1), 0); + rb_define_method(rb_klass, "hu2", RUBY_METHOD_FUNC(rb_hu2), 0); + rb_define_method(rb_klass, "hu3", RUBY_METHOD_FUNC(rb_hu3), 0); + rb_define_method(rb_klass, "hu4", RUBY_METHOD_FUNC(rb_hu4), 0); + rb_define_method(rb_klass, "hu5", RUBY_METHOD_FUNC(rb_hu5), 0); + rb_define_method(rb_klass, "hu6", RUBY_METHOD_FUNC(rb_hu6), 0); + rb_define_method(rb_klass, "hu7", RUBY_METHOD_FUNC(rb_hu7), 0); +} + +__NAMESPACE_END_CVHUMOMENTS +__NAMESPACE_END_OPENCV diff --git a/ext/opencv/cvhumoments.h b/ext/opencv/cvhumoments.h new file mode 100644 index 00000000..580f6708 --- /dev/null +++ b/ext/opencv/cvhumoments.h @@ -0,0 +1,51 @@ +/************************************************************ + + cvhumoments.h - + + $Author: ser1zw $ + + Copyright (C) 2011 ser1zw + +************************************************************/ +#ifndef RUBY_OPENCV_CVHUMOMENTS_H +#define RUBY_OPENCV_CVHUMOMENTS_H + +#include "opencv.h" + +#define __NAMESPACE_BEGIN_CVHUMOMENTS namespace cCvHuMoments { +#define __NAMESPACE_END_CVHUMOMENTS } + +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVHUMOMENTS + +VALUE rb_class(); + +void init_ruby_class(); + +VALUE rb_allocate(VALUE klass); +VALUE rb_initialize(VALUE src_moments, VALUE self); + +VALUE rb_hu1(VALUE self); +VALUE rb_hu2(VALUE self); +VALUE rb_hu3(VALUE self); +VALUE rb_hu4(VALUE self); +VALUE rb_hu5(VALUE self); +VALUE rb_hu6(VALUE self); +VALUE rb_hu7(VALUE self); +VALUE rb_to_ary(VALUE self); + +VALUE new_object(CvMoments *cvmoments); + +__NAMESPACE_END_CVHUMOMENTS + +inline CvHuMoments* +CVHUMOMENTS(VALUE object) +{ + CvHuMoments *ptr; + Data_Get_Struct(object, CvHuMoments, ptr); + return ptr; +} + +__NAMESPACE_END_OPENCV + +#endif // RUBY_OPENCV_CVHUMOMENTS_H diff --git a/ext/opencv/cvline.cpp b/ext/opencv/cvline.cpp new file mode 100644 index 00000000..20e33982 --- /dev/null +++ b/ext/opencv/cvline.cpp @@ -0,0 +1,159 @@ +/************************************************************ + + cvline.cpp - + + $Author: lsxi $ + + Copyright (C) 2005-2006 Masakazu Yonekura + +************************************************************/ +#include "cvline.h" +/* + * Document-class: OpenCV::CvLine + * + * Line parameters represented by a two-element (rho, theta) + * for CvMat#hough_lines + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVLINE + +VALUE rb_klass; + +VALUE +rb_class() +{ + return rb_klass; +} + +VALUE +rb_allocate(VALUE klass) +{ + CvLine *ptr; + return Data_Make_Struct(klass, CvLine, 0, -1, ptr); +} + +/* + * Returns distance from the coordinate origin (0, 0) + * @overload rho + * @return [Number] Distance from the coordinate origin + */ +VALUE +rb_rho(VALUE self) +{ + return rb_float_new(CVLINE(self)->rho); +} + +/* + * Set distance from the coordinate origin (0, 0) + * @overload rho=(value) + * @param value [Number] Distance from the coordinate origin + */ +VALUE +rb_set_rho(VALUE self, VALUE rho) +{ + CVLINE(self)->rho = NUM2DBL(rho); + return self; +} + +/* + * Returns line rotation angle in radians + * @overload theta + * @return [Number] Line rotation angle in radians + */ +VALUE +rb_theta(VALUE self) +{ + return rb_float_new(CVLINE(self)->theta); +} + +/* + * Set line rotation angle in radians + * @overload theta=(value) + * @param value [Number] Line rotation angle + */ +VALUE +rb_set_theta(VALUE self, VALUE theta) +{ + CVLINE(self)->theta = NUM2DBL(theta); + return self; +} + +/* + * Returns value of rho, theta + * @overload [](index) + * @param index [Integer] Index + * @return [Number] If index = 0, returns rho, else if index = 1, returns theta. + */ +VALUE +rb_aref(VALUE self, VALUE index) +{ + switch (NUM2INT(index)) { + case 0: + return DBL2NUM(CVLINE(self)->rho); + break; + case 1: + return DBL2NUM(CVLINE(self)->theta); + break; + default: + rb_raise(rb_eIndexError, "index should be 0...2"); + break; + } + return Qnil; +} + +/* + * Set value of rho, theta + * @overload []=(index, value) + * @param index [Integer] Index + * @param value [Number] Value + * @return [Number] If index = 0, set rho, else if index = 1, set theta. + */ +VALUE +rb_aset(VALUE self, VALUE index, VALUE value) +{ + switch (NUM2INT(index)) { + case 0: + CVLINE(self)->rho = NUM2DBL(value); + break; + case 1: + CVLINE(self)->theta = NUM2DBL(value); + break; + default: + rb_raise(rb_eIndexError, "index should be 0...2"); + break; + } + return value; +} + +VALUE +new_object(CvLine line) +{ + VALUE object = rb_allocate(rb_klass); + *CVLINE(object) = line; + return object; +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + VALUE opencv = rb_module_opencv(); + + rb_klass = rb_define_class_under(opencv, "CvLine", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_method(rb_klass, "rho", RUBY_METHOD_FUNC(rb_rho), 0); + rb_define_method(rb_klass, "rho=", RUBY_METHOD_FUNC(rb_set_rho), 1); + rb_define_method(rb_klass, "theta", RUBY_METHOD_FUNC(rb_theta), 0); + rb_define_method(rb_klass, "theta=", RUBY_METHOD_FUNC(rb_set_theta), 1); + rb_define_method(rb_klass, "[]", RUBY_METHOD_FUNC(rb_aref), 1); + rb_define_method(rb_klass, "[]=", RUBY_METHOD_FUNC(rb_aset), 2); +} + +__NAMESPACE_END_CVLINE +__NAMESPACE_END_OPENCV diff --git a/ext/cvline.h b/ext/opencv/cvline.h similarity index 81% rename from ext/cvline.h rename to ext/opencv/cvline.h index 6accb738..a5618a90 100644 --- a/ext/cvline.h +++ b/ext/opencv/cvline.h @@ -12,12 +12,12 @@ #include "opencv.h" -#define __NAMESPACE_BEGIN_CVLINE namespace cCvLine{ +#define __NAMESPACE_BEGIN_CVLINE namespace cCvLine { #define __NAMESPACE_END_CVLINE } __NAMESPACE_BEGIN_OPENCV -typedef struct CvLine{ +typedef struct CvLine { float rho; float theta; } CvLine; @@ -26,7 +26,7 @@ __NAMESPACE_BEGIN_CVLINE VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_allocate(VALUE klass); VALUE rb_initialize(int argc, VALUE *argv, VALUE self); @@ -34,6 +34,8 @@ VALUE rb_rho(VALUE self); VALUE rb_set_rho(VALUE self, VALUE rho); VALUE rb_theta(VALUE self); VALUE rb_set_theta(VALUE self, VALUE theta); +VALUE rb_aref(VALUE self, VALUE index); +VALUE rb_aset(VALUE self, VALUE index, VALUE value); VALUE new_object(CvLine line); diff --git a/ext/opencv/cvmat.cpp b/ext/opencv/cvmat.cpp new file mode 100644 index 00000000..0f062eaa --- /dev/null +++ b/ext/opencv/cvmat.cpp @@ -0,0 +1,6086 @@ +/************************************************************ + + cvmat.cpp - + + $Author: lsxi $ + + Copyright (C) 2005-2008 Masakazu Yonekura + +************************************************************/ +#include "cvmat.h" +/* + * Document-class: OpenCV::CvMat + * + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVMAT + +#define DRAWING_OPTION(opt) rb_get_option_table(rb_klass, "DRAWING_OPTION", opt) +#define DO_COLOR(opt) VALUE_TO_CVSCALAR(LOOKUP_HASH(opt, "color")) +#define DO_THICKNESS(opt) NUM2INT(LOOKUP_HASH(opt, "thickness")) +#define DO_LINE_TYPE(opt) rb_drawing_option_line_type(opt) +#define DO_SHIFT(opt) NUM2INT(LOOKUP_HASH(opt, "shift")) +#define DO_IS_CLOSED(opt) TRUE_OR_FALSE(LOOKUP_HASH(opt, "is_closed")) + +#define GOOD_FEATURES_TO_TRACK_OPTION(opt) rb_get_option_table(rb_klass, "GOOD_FEATURES_TO_TRACK_OPTION", opt) +#define GF_MAX(opt) NUM2INT(LOOKUP_HASH(opt, "max")) +#define GF_MASK(opt) MASK(LOOKUP_HASH(opt, "mask")) +#define GF_BLOCK_SIZE(opt) NUM2INT(LOOKUP_HASH(opt, "block_size")) +#define GF_USE_HARRIS(opt) TRUE_OR_FALSE(LOOKUP_HASH(opt, "use_harris")) +#define GF_K(opt) NUM2DBL(LOOKUP_HASH(opt, "k")) + +#define FLOOD_FILL_OPTION(opt) rb_get_option_table(rb_klass, "FLOOD_FILL_OPTION", opt) +#define FF_CONNECTIVITY(opt) NUM2INT(LOOKUP_HASH(opt, "connectivity")) +#define FF_FIXED_RANGE(opt) TRUE_OR_FALSE(LOOKUP_HASH(opt, "fixed_range")) +#define FF_MASK_ONLY(opt) TRUE_OR_FALSE(LOOKUP_HASH(opt, "mask_only")) + +#define FIND_CONTOURS_OPTION(opt) rb_get_option_table(rb_klass, "FIND_CONTOURS_OPTION", opt) +#define FC_MODE(opt) NUM2INT(LOOKUP_HASH(opt, "mode")) +#define FC_METHOD(opt) NUM2INT(LOOKUP_HASH(opt, "method")) +#define FC_OFFSET(opt) VALUE_TO_CVPOINT(LOOKUP_HASH(opt, "offset")) + +#define OPTICAL_FLOW_HS_OPTION(opt) rb_get_option_table(rb_klass, "OPTICAL_FLOW_HS_OPTION", opt) +#define HS_LAMBDA(opt) NUM2DBL(LOOKUP_HASH(opt, "lambda")) +#define HS_CRITERIA(opt) VALUE_TO_CVTERMCRITERIA(LOOKUP_HASH(opt, "criteria")) + +#define OPTICAL_FLOW_BM_OPTION(opt) rb_get_option_table(rb_klass, "OPTICAL_FLOW_BM_OPTION", opt) +#define BM_BLOCK_SIZE(opt) VALUE_TO_CVSIZE(LOOKUP_HASH(opt, "block_size")) +#define BM_SHIFT_SIZE(opt) VALUE_TO_CVSIZE(LOOKUP_HASH(opt, "shift_size")) +#define BM_MAX_RANGE(opt) VALUE_TO_CVSIZE(LOOKUP_HASH(opt, "max_range")) + +#define FIND_FUNDAMENTAL_MAT_OPTION(opt) rb_get_option_table(rb_klass, "FIND_FUNDAMENTAL_MAT_OPTION", opt) +#define FFM_WITH_STATUS(opt) TRUE_OR_FALSE(LOOKUP_HASH(opt, "with_status")) +#define FFM_MAXIMUM_DISTANCE(opt) NUM2DBL(LOOKUP_HASH(opt, "maximum_distance")) +#define FFM_DESIRABLE_LEVEL(opt) NUM2DBL(LOOKUP_HASH(opt, "desirable_level")) + +VALUE rb_klass; + +int +rb_drawing_option_line_type(VALUE drawing_option) +{ + VALUE line_type = LOOKUP_HASH(drawing_option, "line_type"); + if (FIXNUM_P(line_type)) { + return FIX2INT(line_type); + } + else if (line_type == ID2SYM(rb_intern("aa"))) { + return CV_AA; + } + return 0; +} + +int* +hash_to_format_specific_param(VALUE hash) +{ + Check_Type(hash, T_HASH); + const int flags[] = { + CV_IMWRITE_JPEG_QUALITY, + CV_IMWRITE_PNG_COMPRESSION, + CV_IMWRITE_PNG_STRATEGY, + CV_IMWRITE_PNG_STRATEGY_DEFAULT, + CV_IMWRITE_PNG_STRATEGY_FILTERED, + CV_IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY, + CV_IMWRITE_PNG_STRATEGY_RLE, + CV_IMWRITE_PNG_STRATEGY_FIXED, + CV_IMWRITE_PXM_BINARY + }; + const int flag_size = sizeof(flags) / sizeof(int); + + int* params = (int*)ALLOC_N(int, RHASH_SIZE(hash) * 2); + for (int i = 0, n = 0; i < flag_size; i++) { + VALUE val = rb_hash_lookup(hash, INT2FIX(flags[i])); + if (!NIL_P(val)) { + params[n] = flags[i]; + params[n + 1] = NUM2INT(val); + n += 2; + } + } + + return params; +} + +VALUE +rb_class() +{ + return rb_klass; +} + +VALUE +rb_allocate(VALUE klass) +{ + return OPENCV_OBJECT(klass, 0); +} + +/* + * Creates a matrix + * @overload new(rows, cols, depth = CV_8U, channels = 3) + * @param row [Integer] Number of rows in the matrix + * @param col [Integer] Number of columns in the matrix + * @param depth [Integer, Symbol] Depth type in the matrix. + * The type of the matrix elements in the form of constant CV_ + * or symbol :cv, where S=signed, U=unsigned, F=float. + * @param channels [Integer] Number of channels in the matrix + * @return [CvMat] Created matrix + * @opencv_func cvCreateMat + * @example + * mat1 = CvMat.new(3, 4) # Creates a 3-channels 3x4 matrix whose elements are 8bit unsigned. + * mat2 = CvMat.new(5, 6, CV_32F, 1) # Creates a 1-channel 5x6 matrix whose elements are 32bit float. + * mat3 = CvMat.new(5, 6, :cv32f, 1) # Same as CvMat.new(5, 6, CV_32F, 1) + */ +VALUE +rb_initialize(int argc, VALUE *argv, VALUE self) +{ + VALUE row, column, depth, channel; + rb_scan_args(argc, argv, "22", &row, &column, &depth, &channel); + + int ch = (argc < 4) ? 3 : NUM2INT(channel); + CvMat *ptr = rb_cvCreateMat(NUM2INT(row), NUM2INT(column), + CV_MAKETYPE(CVMETHOD("DEPTH", depth, CV_8U), ch)); + free(DATA_PTR(self)); + DATA_PTR(self) = ptr; + + return self; +} + +/* + * Load an image from the specified file + * @overload load(filename, iscolor = 1) + * @param filename [String] Name of file to be loaded + * @param iscolor [Integer] Flags specifying the color type of a loaded image: + * - > 0 Return a 3-channel color image. + * - = 0 Return a grayscale image. + * - < 0 Return the loaded image as is. + * @return [CvMat] Loaded image + * @opencv_func cvLoadImageM + * @scope class + */ +VALUE +rb_load_imageM(int argc, VALUE *argv, VALUE self) +{ + VALUE filename, iscolor; + rb_scan_args(argc, argv, "11", &filename, &iscolor); + Check_Type(filename, T_STRING); + + int _iscolor; + if (NIL_P(iscolor)) { + _iscolor = CV_LOAD_IMAGE_COLOR; + } + else { + Check_Type(iscolor, T_FIXNUM); + _iscolor = FIX2INT(iscolor); + } + + CvMat *mat = NULL; + try { + mat = cvLoadImageM(StringValueCStr(filename), _iscolor); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + if (mat == NULL) { + rb_raise(rb_eStandardError, "file does not exist or invalid format image."); + } + return OPENCV_OBJECT(rb_klass, mat); +} + +/* + * Encodes an image into a memory buffer. + * + * @overload encode_image(ext, params = nil) + * @param ext [String] File extension that defines the output format ('.jpg', '.png', ...) + * @param params [Hash] - Format-specific parameters. + * @option params [Integer] CV_IMWRITE_JPEG_QUALITY (95) For JPEG, it can be a quality + * ( CV_IMWRITE_JPEG_QUALITY ) from 0 to 100 (the higher is the better). + * @option params [Integer] CV_IMWRITE_PNG_COMPRESSION (3) For PNG, it can be the compression + * level ( CV_IMWRITE_PNG_COMPRESSION ) from 0 to 9. A higher value means a smaller size + * and longer compression time. + * @option params [Integer] CV_IMWRITE_PXM_BINARY (1) For PPM, PGM, or PBM, it can be a binary + * format flag ( CV_IMWRITE_PXM_BINARY ), 0 or 1. + * @return [Array] Encoded image as array of bytes. + * @opencv_func cvEncodeImage + * @example + * jpg = CvMat.load('image.jpg') + * bytes1 = jpg.encode_image('.jpg') # Encodes a JPEG image which quality is 95 + * bytes2 = jpg.encode_image('.jpg', CV_IMWRITE_JPEG_QUALITY => 10) # Encodes a JPEG image which quality is 10 + * + * png = CvMat.load('image.png') + * bytes3 = mat.encode_image('.png', CV_IMWRITE_PNG_COMPRESSION => 1) # Encodes a PNG image which compression level is 1 + */ +VALUE +rb_encode_imageM(int argc, VALUE *argv, VALUE self) +{ + VALUE _ext, _params; + rb_scan_args(argc, argv, "11", &_ext, &_params); + Check_Type(_ext, T_STRING); + const char* ext = RSTRING_PTR(_ext); + CvMat* buff = NULL; + int* params = NULL; + + if (!NIL_P(_params)) { + params = hash_to_format_specific_param(_params); + } + + try { + buff = cvEncodeImage(ext, CVARR(self), params); + } + catch (cv::Exception& e) { + if (params != NULL) { + free(params); + params = NULL; + } + raise_cverror(e); + } + if (params != NULL) { + free(params); + params = NULL; + } + + const int size = buff->rows * buff->cols; + VALUE array = rb_ary_new2(size); + for (int i = 0; i < size; i++) { + rb_ary_store(array, i, CHR2FIX(CV_MAT_ELEM(*buff, char, 0, i))); + } + + try { + cvReleaseMat(&buff); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return array; +} + +CvMat* +prepare_decoding(int argc, VALUE *argv, int* iscolor, int* need_release) +{ + VALUE _buff, _iscolor; + rb_scan_args(argc, argv, "11", &_buff, &_iscolor); + *iscolor = NIL_P(_iscolor) ? CV_LOAD_IMAGE_COLOR : NUM2INT(_iscolor); + + CvMat* buff = NULL; + *need_release = 0; + switch (TYPE(_buff)) { + case T_STRING: + _buff = rb_funcall(_buff, rb_intern("unpack"), 1, rb_str_new("c*", 2)); + case T_ARRAY: { + int cols = RARRAY_LEN(_buff); + *need_release = 1; + try { + buff = rb_cvCreateMat(1, cols, CV_8UC1); + VALUE *ary_ptr = RARRAY_PTR(_buff); + for (int i = 0; i < cols; i++) { + CV_MAT_ELEM(*buff, char, 0, i) = NUM2CHR(ary_ptr[i]); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + break; + } + case T_DATA: + if (rb_obj_is_kind_of(_buff, cCvMat::rb_class()) == Qtrue) { + buff = CVMAT(_buff); + break; + } + default: + raise_typeerror(_buff, "CvMat, Array or String"); + } + + return buff; +} + +/* + * Reads an image from a buffer in memory. + * @overload decode_image(buf, iscolor = 1) + * @param buf [CvMat, Array, String] Input array of bytes + * @param iscolor [Integer] Flags specifying the color type of a decoded image (the same flags as CvMat#load) + * @return [CvMat] Loaded matrix + * @opencv_func cvDecodeImageM + */ +VALUE +rb_decode_imageM(int argc, VALUE *argv, VALUE self) +{ + int iscolor, need_release; + CvMat* buff = prepare_decoding(argc, argv, &iscolor, &need_release); + CvMat* mat_ptr = NULL; + try { + mat_ptr = cvDecodeImageM(buff, iscolor); + if (need_release) { + cvReleaseMat(&buff); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return OPENCV_OBJECT(rb_klass, mat_ptr); +} + +/* + * nodoc + */ +VALUE +rb_method_missing(int argc, VALUE *argv, VALUE self) +{ + VALUE name, args, method; + rb_scan_args(argc, argv, "1*", &name, &args); + method = rb_funcall(name, rb_intern("to_s"), 0); + if (RARRAY_LEN(args) != 0 || !rb_respond_to(rb_module_opencv(), rb_intern(StringValuePtr(method)))) + return rb_call_super(argc, argv); + return rb_funcall(rb_module_opencv(), rb_intern(StringValuePtr(method)), 1, self); +} + +/* + * @overload to_s + * @return [String] String representation of the matrix + */ +VALUE +rb_to_s(VALUE self) +{ + const int i = 6; + VALUE str[i]; + str[0] = rb_str_new2("<%s:%dx%d,depth=%s,channel=%d>"); + str[1] = rb_str_new2(rb_class2name(CLASS_OF(self))); + str[2] = rb_width(self); + str[3] = rb_height(self); + str[4] = rb_depth(self); + str[5] = rb_channel(self); + return rb_f_sprintf(i, str); +} + +/* + * Tests whether a coordinate or rectangle is inside of the matrix + * @overload inside?(point) + * @param obj [#x, #y] Tested coordinate + * @overload inside?(rect) + * @param obj [#x, #y, #width, #height] Tested rectangle + * @return [Boolean] If the point or rectangle is inside of the matrix, return true. + * If not, return false. + */ +VALUE +rb_inside_q(VALUE self, VALUE object) +{ + if (cCvPoint::rb_compatible_q(cCvPoint::rb_class(), object)) { + CvMat *mat = CVMAT(self); + int x = NUM2INT(rb_funcall(object, rb_intern("x"), 0)); + int y = NUM2INT(rb_funcall(object, rb_intern("y"), 0)); + if (cCvRect::rb_compatible_q(cCvRect::rb_class(), object)) { + int width = NUM2INT(rb_funcall(object, rb_intern("width"), 0)); + int height = NUM2INT(rb_funcall(object, rb_intern("height"), 0)); + return (x >= 0) && (y >= 0) && (x < mat->width) && ((x + width) < mat->width) + && (y < mat->height) && ((y + height) < mat->height) ? Qtrue : Qfalse; + } + else { + return (x >= 0) && (y >= 0) && (x < mat->width) && (y < mat->height) ? Qtrue : Qfalse; + } + } + rb_raise(rb_eArgError, "argument 1 should have method \"x\", \"y\""); + return Qnil; +} + +/* + * Creates a structuring element from the matrix for morphological operations. + * @overload to_IplConvKernel(anchor) + * @param anchor [CvPoint] Anchor position within the element + * @return [IplConvKernel] Created IplConvKernel + * @opencv_func cvCreateStructuringElementEx + */ +VALUE +rb_to_IplConvKernel(VALUE self, VALUE anchor) +{ + CvMat *src = CVMAT(self); + CvPoint p = VALUE_TO_CVPOINT(anchor); + IplConvKernel *kernel = rb_cvCreateStructuringElementEx(src->cols, src->rows, p.x, p.y, + CV_SHAPE_CUSTOM, src->data.i); + return DEPEND_OBJECT(cIplConvKernel::rb_class(), kernel, self); +} + +/* + * Creates a mask (1-channel 8bit unsinged image whose elements are 0) from the matrix. + * The size of the mask is the same as source matrix. + * @overload create_mask + * @return [CvMat] Created mask + */ +VALUE +rb_create_mask(VALUE self) +{ + VALUE mask = cCvMat::new_object(cvGetSize(CVARR(self)), CV_8UC1); + try { + cvZero(CVARR(self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return mask; +} + +/* + * Returns number of columns of the matrix. + * @overload width + * @return [Integer] Number of columns of the matrix + */ +VALUE +rb_width(VALUE self) +{ + return INT2NUM(CVMAT(self)->width); +} + +/* + * Returns number of rows of the matrix. + * @overload rows + * @return [Integer] Number of rows of the matrix + */ +VALUE +rb_height(VALUE self) +{ + return INT2NUM(CVMAT(self)->height); +} + +/* + * Returns depth type of the matrix + * @overload depth + * @return [Symbol] Depth type in the form of symbol :cv, + * where s=signed, u=unsigned, f=float. + */ +VALUE +rb_depth(VALUE self) +{ + return rb_hash_lookup(rb_funcall(rb_const_get(rb_module_opencv(), rb_intern("DEPTH")), rb_intern("invert"), 0), + INT2FIX(CV_MAT_DEPTH(CVMAT(self)->type))); +} + +/* + * Returns number of channels of the matrix + * @overload channel + * @return [Integer] Number of channels of the matrix + */ +VALUE +rb_channel(VALUE self) +{ + return INT2FIX(CV_MAT_CN(CVMAT(self)->type)); +} + +/* + * @overload data + * @deprecated This method will be removed. + */ +VALUE +rb_data(VALUE self) +{ + IplImage *image = IPLIMAGE(self); + return rb_str_new((char *)image->imageData, image->imageSize); +} + +/* + * Makes a clone of an object. + * @overload clone + * @return [CvMat] Clone of the object + * @opencv_func cvClone + */ +VALUE +rb_clone(VALUE self) +{ + VALUE clone = rb_obj_clone(self); + try { + DATA_PTR(clone) = cvClone(CVARR(self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return clone; +} + +/* + * Copies one array to another. + * + * The function copies selected elements from an input array to an output array: + * dst(I) = src(I) if mask(I) != 0 + * + * @overload copy(dst = nil, mask = nil) + * @param dst [CvMat] The destination array. + * @param mask [CvMat] Operation mask, 8-bit single channel array; + * specifies elements of the destination array to be changed. + * @return [CvMat] Copy of the array + * @opencv_func cvCopy + */ +VALUE +rb_copy(int argc, VALUE *argv, VALUE self) +{ + VALUE _dst, _mask; + rb_scan_args(argc, argv, "02", &_dst, &_mask); + + CvMat* mask = MASK(_mask); + CvArr *src = CVARR(self); + if (NIL_P(_dst)) { + CvSize size = cvGetSize(src); + _dst = new_mat_kind_object(size, self); + } + + try { + cvCopy(src, CVARR_WITH_CHECK(_dst), mask); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return _dst; +} + +VALUE +copy(VALUE mat) +{ + return rb_clone(mat); +} + +inline VALUE +rb_to_X_internal(VALUE self, int depth) +{ + CvMat *src = CVMAT(self); + VALUE dest = new_object(src->rows, src->cols, CV_MAKETYPE(depth, CV_MAT_CN(src->type))); + try { + cvConvert(src, CVMAT(dest)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Converts the matrix to 8bit unsigned. + * @overload to_8u + * @return [CvMat] Converted matrix which depth is 8bit unsigned. + * The size and channels of the new matrix are same as the source. + * @opencv_func cvConvert + */ +VALUE +rb_to_8u(VALUE self) +{ + return rb_to_X_internal(self, CV_8U); +} + +/* + * Converts the matrix to 8bit signed. + * @overload to_8s + * @return [CvMat] Converted matrix which depth is 8bit signed. + * The size and channels of the new matrix are same as the source. + * @opencv_func cvConvert + */ +VALUE +rb_to_8s(VALUE self) +{ + return rb_to_X_internal(self, CV_8S); +} + +/* + * Converts the matrix to 16bit unsigned. + * @overload to_16u + * @return [CvMat] Converted matrix which depth is 16bit unsigned. + * The size and channels of the new matrix are same as the source. + * @opencv_func cvConvert + */ +VALUE rb_to_16u(VALUE self) +{ + return rb_to_X_internal(self, CV_16U); +} + +/* + * Converts the matrix to 16bit signed. + * @overload to_16s + * @return [CvMat] Converted matrix which depth is 16bit signed. + * The size and channels of the new matrix are same as the source. + * @opencv_func cvConvert + */ +VALUE +rb_to_16s(VALUE self) +{ + return rb_to_X_internal(self, CV_16S); +} + +/* + * Converts the matrix to 32bit signed. + * @overload to_32s + * @return [CvMat] Converted matrix which depth is 32bit signed. + * The size and channels of the new matrix are same as the source. + * @opencv_func cvConvert + */ +VALUE +rb_to_32s(VALUE self) +{ + return rb_to_X_internal(self, CV_32S); +} + +/* + * Converts the matrix to 32bit float. + * @overload to_32f + * @return [CvMat] Converted matrix which depth is 32bit float. + * The size and channels of the new matrix are same as the source. + * @opencv_func cvConvert + */ +VALUE +rb_to_32f(VALUE self) +{ + return rb_to_X_internal(self, CV_32F); +} + +/* + * Converts the matrix to 64bit float. + * @overload to_64f + * @return [CvMat] Converted matrix which depth is 64bit float. + * The size and channels of the new matrix are same as the source. + * @opencv_func cvConvert + */ +VALUE +rb_to_64f(VALUE self) +{ + return rb_to_X_internal(self, CV_64F); +} + +/* + * Returns whether the matrix is a vector. + * @overload vector? + * @return [Boolean] If width or height of the matrix is 1, returns true. + * if not, returns false. + */ +VALUE +rb_vector_q(VALUE self) +{ + CvMat *mat = CVMAT(self); + return (mat->width == 1|| mat->height == 1) ? Qtrue : Qfalse; +} + +/* + * Returns whether the matrix is a square. + * @overload square? + * @return [Boolean] If width = height, returns true. + * if not, returns false. + */ +VALUE +rb_square_q(VALUE self) +{ + CvMat *mat = CVMAT(self); + return mat->width == mat->height ? Qtrue : Qfalse; +} + +/************************************************************ + cxcore function +************************************************************/ +/* + * Converts an object to CvMat + * @overload to_CvMat + * @return [CvMat] Converted matrix + */ +VALUE +rb_to_CvMat(VALUE self) +{ + // CvMat#to_CvMat aborts when self's class is CvMat. + if (CLASS_OF(self) == rb_klass) + return self; + + CvMat *mat = NULL; + try { + mat = cvGetMat(CVARR(self), RB_CVALLOC(CvMat)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return DEPEND_OBJECT(rb_klass, mat, self); +} + +/* + * Returns matrix corresponding to the rectangular sub-array of input image or matrix + * + * @overload sub_rect(rect) + * @param rect [CvRect] Zero-based coordinates of the rectangle of interest. + * @overload sub_rect(topleft, size) + * @param topleft [CvPoint] Top-left coordinates of the rectangle of interest + * @param size [CvSize] Size of the rectangle of interest + * @overload sub_rect(x, y, width, height) + * @param x [Integer] X-coordinate of the rectangle of interest + * @param y [Integer] Y-coordinate of the rectangle of interest + * @param width [Integer] Width of the rectangle of interest + * @param height [Integer] Height of the rectangle of interest + * @return [CvMat] Sub-array of matrix + * @opencv_func cvGetSubRect + */ +VALUE +rb_sub_rect(VALUE self, VALUE args) +{ + CvRect area; + CvPoint topleft; + CvSize size; + switch(RARRAY_LEN(args)) { + case 1: + area = VALUE_TO_CVRECT(RARRAY_PTR(args)[0]); + break; + case 2: + topleft = VALUE_TO_CVPOINT(RARRAY_PTR(args)[0]); + size = VALUE_TO_CVSIZE(RARRAY_PTR(args)[1]); + area.x = topleft.x; + area.y = topleft.y; + area.width = size.width; + area.height = size.height; + break; + case 4: + area.x = NUM2INT(RARRAY_PTR(args)[0]); + area.y = NUM2INT(RARRAY_PTR(args)[1]); + area.width = NUM2INT(RARRAY_PTR(args)[2]); + area.height = NUM2INT(RARRAY_PTR(args)[3]); + break; + default: + rb_raise(rb_eArgError, "wrong number of arguments (%ld of 1 or 2 or 4)", RARRAY_LEN(args)); + } + + CvMat* mat = NULL; + try { + mat = cvGetSubRect(CVARR(self), RB_CVALLOC(CvMat), area); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return DEPEND_OBJECT(rb_klass, mat, self); +} + +void +rb_get_range_index(VALUE index, int* start, int *end) { + if (rb_obj_is_kind_of(index, rb_cRange)) { + *start = NUM2INT(rb_funcall3(index, rb_intern("begin"), 0, NULL)); + *end = NUM2INT(rb_funcall3(index, rb_intern("end"), 0, NULL)); + if (rb_funcall3(index, rb_intern("exclude_end?"), 0, NULL) == Qfalse) { + (*end)++; + } + } + else { + *start = NUM2INT(index); + *end = *start + 1; + } +} + +/* + * Returns array of row or row span. + * @overload get_rows(index, delta_row = 1) + * @param index [Integer] Zero-based index of the selected row + * @param delta_row [Integer] Index step in the row span. + * @return [CvMat] Selected row + * @overload get_rows(range, delta_row = 1) + * @param range [Range] Zero-based index range of the selected row + * @param delta_row [Integer] Index step in the row span. + * @return [CvMat] Selected rows + * @opencv_func cvGetRows + */ +VALUE +rb_get_rows(int argc, VALUE* argv, VALUE self) +{ + VALUE row_val, delta_val; + rb_scan_args(argc, argv, "11", &row_val, &delta_val); + + int start, end; + rb_get_range_index(row_val, &start, &end); + int delta = NIL_P(delta_val) ? 1 : NUM2INT(delta_val); + CvMat* submat = RB_CVALLOC(CvMat); + try { + cvGetRows(CVARR(self), submat, start, end, delta); + } + catch (cv::Exception& e) { + cvFree(&submat); + raise_cverror(e); + } + + return DEPEND_OBJECT(rb_klass, submat, self); +} + +/* + * Returns array of column or column span. + * @overload get_cols(index) + * @param index [Integer] Zero-based index of the selected column + * @return [CvMat] Selected column + * @overload get_cols(range) + * @param range [Range] Zero-based index range of the selected column + * @return [CvMat] Selected columns + * @opencv_func cvGetCols + */ +VALUE +rb_get_cols(VALUE self, VALUE col) +{ + int start, end; + rb_get_range_index(col, &start, &end); + CvMat* submat = RB_CVALLOC(CvMat); + try { + cvGetCols(CVARR(self), submat, start, end); + } + catch (cv::Exception& e) { + cvFree(&submat); + raise_cverror(e); + } + + return DEPEND_OBJECT(rb_klass, submat, self); +} + +/* + * Calls block once for each row in the matrix, passing that + * row as a parameter. + * @yield [row] Each row in the matrix + * @return [CvMat] self + * @opencv_func cvGetRow + * @todo To return an enumerator if no block is given + */ +VALUE +rb_each_row(VALUE self) +{ + int rows = CVMAT(self)->rows; + CvMat* row = NULL; + for (int i = 0; i < rows; ++i) { + try { + row = cvGetRow(CVARR(self), RB_CVALLOC(CvMat), i); + } + catch (cv::Exception& e) { + if (row != NULL) + cvReleaseMat(&row); + raise_cverror(e); + } + rb_yield(DEPEND_OBJECT(rb_klass, row, self)); + } + return self; +} + +/* + * Calls block once for each column in the matrix, passing that + * column as a parameter. + * @yield [col] Each column in the matrix + * @return [CvMat] self + * @opencv_func cvGetCol + * @todo To return an enumerator if no block is given + */ +VALUE +rb_each_col(VALUE self) +{ + int cols = CVMAT(self)->cols; + CvMat *col = NULL; + for (int i = 0; i < cols; ++i) { + try { + col = cvGetCol(CVARR(self), RB_CVALLOC(CvMat), i); + } + catch (cv::Exception& e) { + if (col != NULL) + cvReleaseMat(&col); + raise_cverror(e); + } + rb_yield(DEPEND_OBJECT(rb_klass, col, self)); + } + return self; +} + +/* + * Returns a specified diagonal of the matrix + * @overload diag(val = 0) + * @param val [Integer] Index of the array diagonal. Zero value corresponds to the main diagonal, + * -1 corresponds to the diagonal above the main, 1 corresponds to the diagonal below the main, + * and so forth. + * @return [CvMat] Specified diagonal + * @opencv_func cvGetDiag + */ +VALUE +rb_diag(int argc, VALUE *argv, VALUE self) +{ + VALUE val; + if (rb_scan_args(argc, argv, "01", &val) < 1) + val = INT2FIX(0); + CvMat* diag = NULL; + try { + diag = cvGetDiag(CVARR(self), RB_CVALLOC(CvMat), NUM2INT(val)); + } + catch (cv::Exception& e) { + cvReleaseMat(&diag); + raise_cverror(e); + } + return DEPEND_OBJECT(rb_klass, diag, self); +} + +/* + * Returns size of the matrix + * @overload size + * @return [CvSize] Size of the matrix + * @opencv_func cvGetSize + */ +VALUE +rb_size(VALUE self) +{ + CvSize size; + try { + size = cvGetSize(CVARR(self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return cCvSize::new_object(size); +} + +/* + * Returns array dimensions sizes + * @overload dims + * @return [Array] Array dimensions sizes. + * For 2d arrays the number of rows (height) goes first, number of columns (width) next. + * @opencv_func cvGetDims + */ +VALUE +rb_dims(VALUE self) +{ + int size[CV_MAX_DIM]; + int dims = 0; + try { + dims = cvGetDims(CVARR(self), size); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + VALUE ary = rb_ary_new2(dims); + for (int i = 0; i < dims; ++i) { + rb_ary_store(ary, i, INT2NUM(size[i])); + } + return ary; +} + +/* + * Returns array size along the specified dimension. + * @overload dim_size(index) + * @param index [Intger] Zero-based dimension index + * (for matrices 0 means number of rows, 1 means number of columns; + * for images 0 means height, 1 means width) + * @return [Integer] Array size + * @opencv_func cvGetDimSize + */ +VALUE +rb_dim_size(VALUE self, VALUE index) +{ + int dimsize = 0; + try { + dimsize = cvGetDimSize(CVARR(self), NUM2INT(index)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return INT2NUM(dimsize); +} + +/* + * Returns a specific array element. + * @overload [](idx0) + * @overload [](idx0, idx1) + * @overload [](idx0, idx1, idx2) + * @overload [](idx0, idx1, idx2, ...) + * @param idx-n [Integer] Zero-based component of the element index + * @return [CvScalar] Array element + * @opencv_func cvGet1D + * @opencv_func cvGet2D + * @opencv_func cvGet3D + * @opencv_func cvGetND + */ +VALUE +rb_aref(VALUE self, VALUE args) +{ + int index[CV_MAX_DIM]; + for (int i = 0; i < RARRAY_LEN(args); ++i) + index[i] = NUM2INT(rb_ary_entry(args, i)); + + CvScalar scalar = cvScalarAll(0); + try { + switch (RARRAY_LEN(args)) { + case 1: + scalar = cvGet1D(CVARR(self), index[0]); + break; + case 2: + scalar = cvGet2D(CVARR(self), index[0], index[1]); + break; + default: + scalar = cvGetND(CVARR(self), index); + break; + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return cCvScalar::new_object(scalar); +} + +/* + * Changes the particular array element + * @overload []=(idx0, value) + * @overload []=(idx0, idx1, value) + * @overload []=(idx0, idx1, idx2, value) + * @overload []=(idx0, idx1, idx2, ..., value) + * @param idx-n [Integer] Zero-based component of the element index + * @param value [CvScalar] The assigned value + * @return [CvMat] self + * @opencv_func cvSet1D + * @opencv_func cvSet2D + * @opencv_func cvSet3D + * @opencv_func cvSetND + */ +VALUE +rb_aset(VALUE self, VALUE args) +{ + CvScalar scalar = VALUE_TO_CVSCALAR(rb_ary_pop(args)); + int index[CV_MAX_DIM]; + for (int i = 0; i < RARRAY_LEN(args); ++i) + index[i] = NUM2INT(rb_ary_entry(args, i)); + + try { + switch (RARRAY_LEN(args)) { + case 1: + cvSet1D(CVARR(self), index[0], scalar); + break; + case 2: + cvSet2D(CVARR(self), index[0], index[1], scalar); + break; + default: + cvSetND(CVARR(self), index, scalar); + break; + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Assigns user data to the array header + * @overload set_data(data) + * @param data [Array] User data + * @return [CvMat] self + * @opencv_func cvSetData + */ +VALUE +rb_set_data(VALUE self, VALUE data) +{ + data = rb_funcall(data, rb_intern("flatten"), 0); + const int DATA_LEN = RARRAY_LEN(data); + CvMat *self_ptr = CVMAT(self); + int depth = CV_MAT_DEPTH(self_ptr->type); + void* array = NULL; + + switch (depth) { + case CV_8U: + array = rb_cvAlloc(sizeof(uchar) * DATA_LEN); + for (int i = 0; i < DATA_LEN; ++i) + ((uchar*)array)[i] = (uchar)(NUM2INT(rb_ary_entry(data, i))); + break; + case CV_8S: + array = rb_cvAlloc(sizeof(char) * DATA_LEN); + for (int i = 0; i < DATA_LEN; ++i) + ((char*)array)[i] = (char)(NUM2INT(rb_ary_entry(data, i))); + break; + case CV_16U: + array = rb_cvAlloc(sizeof(ushort) * DATA_LEN); + for (int i = 0; i < DATA_LEN; ++i) + ((ushort*)array)[i] = (ushort)(NUM2INT(rb_ary_entry(data, i))); + break; + case CV_16S: + array = rb_cvAlloc(sizeof(short) * DATA_LEN); + for (int i = 0; i < DATA_LEN; ++i) + ((short*)array)[i] = (short)(NUM2INT(rb_ary_entry(data, i))); + break; + case CV_32S: + array = rb_cvAlloc(sizeof(int) * DATA_LEN); + for (int i = 0; i < DATA_LEN; ++i) + ((int*)array)[i] = NUM2INT(rb_ary_entry(data, i)); + break; + case CV_32F: + array = rb_cvAlloc(sizeof(float) * DATA_LEN); + for (int i = 0; i < DATA_LEN; ++i) + ((float*)array)[i] = (float)NUM2DBL(rb_ary_entry(data, i)); + break; + case CV_64F: + array = rb_cvAlloc(sizeof(double) * DATA_LEN); + for (int i = 0; i < DATA_LEN; ++i) + ((double*)array)[i] = NUM2DBL(rb_ary_entry(data, i)); + break; + default: + rb_raise(rb_eArgError, "Invalid CvMat depth"); + break; + } + + try { + cvSetData(self_ptr, array, self_ptr->step); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return self; +} + +/* + * Returns a matrix which is set every element to a given value. + * The function copies the scalar value to every selected element of the destination array: + * mat[I] = value if mask(I) != 0 + * + * @overload set(value, mask = nil) Fill value + * @param value [CvScalar] Fill value + * @param mask [CvMat] Operation mask, 8-bit single channel array; + * specifies elements of the destination array to be changed + * @return [CvMat] Matrix which is set every element to a given value. + * @opencv_func cvSet + */ +VALUE +rb_set(int argc, VALUE *argv, VALUE self) +{ + return rb_set_bang(argc, argv, copy(self)); +} + +/* + * Sets every element of the matrix to a given value. + * The function copies the scalar value to every selected element of the destination array: + * mat[I] = value if mask(I) != 0 + * + * @overload set!(value, mask = nil) + * @param (see #set) + * @return [CvMat] self + * @opencv_func cvSet + */ +VALUE +rb_set_bang(int argc, VALUE *argv, VALUE self) +{ + VALUE value, mask; + rb_scan_args(argc, argv, "11", &value, &mask); + try { + cvSet(CVARR(self), VALUE_TO_CVSCALAR(value), MASK(mask)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Saves an image to a specified file. + * The image format is chosen based on the filename extension. + * @overload save_image(filename) + * @param filename [String] Name of the file + * @return [CvMat] self + * @opencv_func cvSaveImage + */ +VALUE +rb_save_image(int argc, VALUE *argv, VALUE self) +{ + VALUE _filename, _params; + rb_scan_args(argc, argv, "11", &_filename, &_params); + Check_Type(_filename, T_STRING); + int *params = NULL; + if (!NIL_P(_params)) { + params = hash_to_format_specific_param(_params); + } + + try { + cvSaveImage(StringValueCStr(_filename), CVARR(self), params); + } + catch (cv::Exception& e) { + if (params != NULL) { + free(params); + params = NULL; + } + raise_cverror(e); + } + if (params != NULL) { + free(params); + params = NULL; + } + + return self; +} + +/* + * Returns cleared array. + * @overload set_zero + * @return [CvMat] Cleared array + * @opencv_func cvSetZero + */ +VALUE +rb_set_zero(VALUE self) +{ + return rb_set_zero_bang(copy(self)); +} + +/* + * Clears the array. + * @overload set_zero! + * @return [CvMat] self + * @opencv_func cvSetZero + */ +VALUE +rb_set_zero_bang(VALUE self) +{ + try { + cvSetZero(CVARR(self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Returns a scaled identity matrix. + * arr(i, j) = value if i = j, 0 otherwise + * @overload identity(value) + * @param value [CvScalar] Value to assign to diagonal elements. + * @return [CvMat] Scaled identity matrix. + * @opencv_func cvSetIdentity + */ +VALUE +rb_set_identity(int argc, VALUE *argv, VALUE self) +{ + return rb_set_identity_bang(argc, argv, copy(self)); +} + +/* + * Initializes a scaled identity matrix. + * arr(i, j) = value if i = j, 0 otherwise + * @overload identity!(value) + * @param (see #identity) + * @return [CvMat] self + * @opencv_func cvSetIdentity + */ +VALUE +rb_set_identity_bang(int argc, VALUE *argv, VALUE self) +{ + VALUE val; + CvScalar value; + if (rb_scan_args(argc, argv, "01", &val) < 1) + value = cvRealScalar(1); + else + value = VALUE_TO_CVSCALAR(val); + + try { + cvSetIdentity(CVARR(self), value); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Returns initialized matrix as following: + * arr(i,j)=(end-start)*(i*cols(arr)+j)/(cols(arr)*rows(arr)) + * @overload range(start, end) + * @param start [Number] The lower inclusive boundary of the range + * @param end [Number] The upper exclusive boundary of the range + * @return [CvMat] Initialized matrix + * @opencv_func cvRange + */ +VALUE +rb_range(VALUE self, VALUE start, VALUE end) +{ + return rb_range_bang(copy(self), start, end); +} + +/* + * Initializes the matrix as following: + * arr(i,j)=(end-start)*(i*cols(arr)+j)/(cols(arr)*rows(arr)) + * @overload range!(start, end) + * @param (see #range) + * @return [CvMat] self + * @opencv_func cvRange + */ +VALUE +rb_range_bang(VALUE self, VALUE start, VALUE end) +{ + try { + cvRange(CVARR(self), NUM2DBL(start), NUM2DBL(end)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Changes shape of matrix/image without copying data. + * @overload reshape(cn, rows=0) + * @param cn [Integer] New number of channels. If the parameter is 0, the number of channels remains the same. + * @param rows [Integer] New number of rows. If the parameter is 0, the number of rows remains the same. + * @return [CvMat] Changed matrix + * @opencv_func cvReshape + * @example + * mat = CvMat.new(3, 3, CV_8U, 3) #=> 3x3 3-channel matrix + * vec = mat.reshape(:rows => 1) #=> 1x9 3-channel matrix + * ch1 = mat.reshape(:channel => 1) #=> 9x3 1-channel matrix + */ +VALUE +rb_reshape(int argc, VALUE *argv, VALUE self) +{ + VALUE cn, rows; + CvMat *mat = NULL; + rb_scan_args(argc, argv, "11", &cn, &rows); + try { + mat = cvReshape(CVARR(self), RB_CVALLOC(CvMat), NUM2INT(cn), IF_INT(rows, 0)); + } + catch (cv::Exception& e) { + if (mat != NULL) + cvReleaseMat(&mat); + raise_cverror(e); + } + return DEPEND_OBJECT(rb_klass, mat, self); +} + +/* + * Fills the destination array with repeated copies of the source array. + * + * @overload repeat(dst) + * @param dst [CvMat] Destination array of the same type as self. + * @return [CvMat] Destination array + * @opencv_func cvRepeat + */ +VALUE +rb_repeat(VALUE self, VALUE object) +{ + try { + cvRepeat(CVARR(self), CVARR_WITH_CHECK(object)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return object; +} + +/* + * Returns a fliped 2D array around vertical, horizontal, or both axes. + * + * @overload flip(flip_mode) + * @param flip_mode [Symbol] Flag to specify how to flip the array. + * - :x - Flipping around the x-axis. + * - :y - Flipping around the y-axis. + * - :xy - Flipping around both axes. + * @return [CvMat] Flipped array + * @opencv_func cvFlip + */ +VALUE +rb_flip(int argc, VALUE *argv, VALUE self) +{ + return rb_flip_bang(argc, argv, copy(self)); +} + +/* + * Flips a 2D array around vertical, horizontal, or both axes. + * + * @overload flip!(flip_mode) + * @param (see #flip) + * @return (see #flip) + * @opencv_func (see #flip) + */ +VALUE +rb_flip_bang(int argc, VALUE *argv, VALUE self) +{ + VALUE format; + int mode = 1; + if (rb_scan_args(argc, argv, "01", &format) > 0) { + Check_Type(format, T_SYMBOL); + ID flip_mode = rb_to_id(format); + if (flip_mode == rb_intern("x")) { + mode = 1; + } + else if (flip_mode == rb_intern("y")) { + mode = 0; + } + else if (flip_mode == rb_intern("xy")) { + mode = -1; + } + } + try { + cvFlip(CVARR(self), NULL, mode); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Divides a multi-channel array into several single-channel arrays. + * + * @overload split + * @return [Array] Array of single-channel arrays + * @opencv_func cvSplit + * @see merge + * @example + * img = CvMat.new(640, 480, CV_8U, 3) #=> 3-channel image + * a = img.split #=> [img-ch1, img-ch2, img-ch3] + */ +VALUE +rb_split(VALUE self) +{ + CvArr* self_ptr = CVARR(self); + int type = cvGetElemType(self_ptr); + int depth = CV_MAT_DEPTH(type), channel = CV_MAT_CN(type); + VALUE dest = rb_ary_new2(channel); + try { + CvArr *dest_ptr[] = { NULL, NULL, NULL, NULL }; + CvSize size = cvGetSize(self_ptr); + for (int i = 0; i < channel; ++i) { + VALUE tmp = new_mat_kind_object(size, self, depth, 1); + rb_ary_store(dest, i, tmp); + dest_ptr[i] = CVARR(tmp); + } + cvSplit(self_ptr, dest_ptr[0], dest_ptr[1], dest_ptr[2], dest_ptr[3]); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return dest; +} + +/* + * Composes a multi-channel array from several single-channel arrays. + * + * @overload merge(src1 = nil, src2 = nil, src3 = nil, src4 = nil) + * @param src-n [CvMat] Source arrays to be merged. + * All arrays must have the same size and the same depth. + * @return [CvMat] Merged array + * @opencv_func cvMerge + * @see split + * @scope class + */ +VALUE +rb_merge(VALUE klass, VALUE args) +{ + int len = RARRAY_LEN(args); + if (len <= 0 || len > 4) { + rb_raise(rb_eArgError, "wrong number of argument (%d for 1..4)", len); + } + CvMat *src[] = { NULL, NULL, NULL, NULL }, *prev_src = NULL; + for (int i = 0; i < len; ++i) { + VALUE object = rb_ary_entry(args, i); + if (NIL_P(object)) + src[i] = NULL; + else { + src[i] = CVMAT_WITH_CHECK(object); + if (CV_MAT_CN(src[i]->type) != 1) + rb_raise(rb_eArgError, "image should be single-channel CvMat."); + if (prev_src == NULL) + prev_src = src[i]; + else { + if (!CV_ARE_SIZES_EQ(prev_src, src[i])) + rb_raise(rb_eArgError, "image size should be same."); + if (!CV_ARE_DEPTHS_EQ(prev_src, src[i])) + rb_raise(rb_eArgError, "image depth should be same."); + } + } + } + // TODO: adapt IplImage + VALUE dest = Qnil; + try { + dest = new_object(cvGetSize(src[0]), CV_MAKETYPE(CV_MAT_DEPTH(src[0]->type), len)); + cvMerge(src[0], src[1], src[2], src[3], CVARR(dest)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Returns shuffled matrix by swapping randomly chosen pairs of the matrix elements on each iteration + * (where each element may contain several components in case of multi-channel arrays) + * + * @overload rand_shuffle(seed = -1, iter_factor = 1) + * @param seed [Integer] Integer value used to initiate a random sequence + * @param iter_factor [Integer] The relative parameter that characterizes intensity of + * the shuffling performed. The number of iterations (i.e. pairs swapped) is + * round(iter_factor*rows(mat)*cols(mat)), so iter_factor = 0 means that no shuffling is done, + * iter_factor = 1 means that the function swaps rows(mat)*cols(mat) random pairs etc + * @return [CvMat] Shuffled matrix + * @opencv_func cvRandShuffle + */ +VALUE +rb_rand_shuffle(int argc, VALUE *argv, VALUE self) +{ + return rb_rand_shuffle_bang(argc, argv, copy(self)); +} + +/* + * Shuffles the matrix by swapping randomly chosen pairs of the matrix elements on each iteration + * (where each element may contain several components in case of multi-channel arrays) + * + * @overload rand_shuffle!(seed = -1, iter_factor = 1) + * @param (see #rand_shuffle) + * @return (see #rand_shuffle) + * @opencv_func (see #rand_shuffle) + */ +VALUE +rb_rand_shuffle_bang(int argc, VALUE *argv, VALUE self) +{ + VALUE seed, iter; + rb_scan_args(argc, argv, "02", &seed, &iter); + try { + if (NIL_P(seed)) + cvRandShuffle(CVARR(self), NULL, IF_INT(iter, 1)); + else { + CvRNG rng = cvRNG(rb_num2ll(seed)); + cvRandShuffle(CVARR(self), &rng, IF_INT(iter, 1)); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Performs a look-up table transform of an array. + * + * @overload lut(lut) + * @param lut [CvMat] Look-up table of 256 elements. In case of multi-channel source array, + * the table should either have a single channel (in this case the same table is used + * for all channels) or the same number of channels as in the source array. + * @return [CvMat] Transformed array + * @opencv_func cvLUT + */ +VALUE +rb_lut(VALUE self, VALUE lut) +{ + VALUE dest = copy(self); + try { + cvLUT(CVARR(self), CVARR(dest), CVARR_WITH_CHECK(lut)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Converts one array to another with optional linear transformation. + * + * @overload convert_scale(params) + * @param params [Hash] Transform parameters + * @option params [Integer] :depth (same as self) Depth of the destination array + * @option params [Number] :scale (1.0) Scale factor + * @option params [Number] :shift (0.0) Value added to the scaled source array elements + * @return [CvMat] Converted array + * @opencv_func cvConvertScale + */ +VALUE +rb_convert_scale(VALUE self, VALUE hash) +{ + Check_Type(hash, T_HASH); + CvMat* self_ptr = CVMAT(self); + VALUE depth = LOOKUP_HASH(hash, "depth"); + VALUE scale = LOOKUP_HASH(hash, "scale"); + VALUE shift = LOOKUP_HASH(hash, "shift"); + + VALUE dest = Qnil; + try { + dest = new_mat_kind_object(cvGetSize(self_ptr), self, + CVMETHOD("DEPTH", depth, CV_MAT_DEPTH(self_ptr->type)), + CV_MAT_CN(self_ptr->type)); + cvConvertScale(self_ptr, CVARR(dest), IF_DBL(scale, 1.0), IF_DBL(shift, 0.0)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Scales, computes absolute values, and converts the result to 8-bit. + * + * @overload convert_scale_abs(params) + * @param params [Hash] Transform parameters + * @option params [Number] :scale (1.0) Scale factor + * @option params [Number] :shift (0.0) Value added to the scaled source array elements + * @return [CvMat] Converted array + * @opencv_func cvConvertScaleAbs + */ +VALUE +rb_convert_scale_abs(VALUE self, VALUE hash) +{ + Check_Type(hash, T_HASH); + CvMat* self_ptr = CVMAT(self); + VALUE scale = LOOKUP_HASH(hash, "scale"); + VALUE shift = LOOKUP_HASH(hash, "shift"); + VALUE dest = Qnil; + try { + dest = new_mat_kind_object(cvGetSize(self_ptr), self, CV_8U, CV_MAT_CN(CVMAT(self)->type)); + cvConvertScaleAbs(self_ptr, CVARR(dest), IF_DBL(scale, 1.0), IF_DBL(shift, 0.0)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Computes the per-element sum of two arrays or an array and a scalar. + * + * @overload add(val, mask = nil) + * @param val [CvMat, CvScalar] Array or scalar to add + * @param mask [CvMat] Optional operation mask, 8-bit single channel array, + * that specifies elements of the destination array to be changed. + * @return [CvMat] Result array + * @opencv_func cvAdd + * @opencv_func cvAddS + */ +VALUE +rb_add(int argc, VALUE *argv, VALUE self) +{ + VALUE val, mask, dest; + rb_scan_args(argc, argv, "11", &val, &mask); + dest = copy(self); + try { + if (rb_obj_is_kind_of(val, rb_klass)) + cvAdd(CVARR(self), CVARR(val), CVARR(dest), MASK(mask)); + else + cvAddS(CVARR(self), VALUE_TO_CVSCALAR(val), CVARR(dest), MASK(mask)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Calculates the per-element difference between two arrays or array and a scalar. + * + * @overload sub(val, mask = nil) + * @param val [CvMat, CvScalar] Array or scalar to subtract + * @param mask [CvMat] Optional operation mask, 8-bit single channel array, + * that specifies elements of the destination array to be changed. + * @return [CvMat] Result array + * @opencv_func cvSub + * @opencv_func cvSubS + */ +VALUE +rb_sub(int argc, VALUE *argv, VALUE self) +{ + VALUE val, mask, dest; + rb_scan_args(argc, argv, "11", &val, &mask); + dest = copy(self); + try { + if (rb_obj_is_kind_of(val, rb_klass)) + cvSub(CVARR(self), CVARR(val), CVARR(dest), MASK(mask)); + else + cvSubS(CVARR(self), VALUE_TO_CVSCALAR(val), CVARR(dest), MASK(mask)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Calculates the per-element scaled product of two arrays. + * + * @overload mul(val, scale = 1.0) + * @param val [CvMat, CvScalar] Array or scalar to multiply + * @param scale [Number] Optional scale factor. + * @return [CvMat] Result array + * @opencv_func cvMul + */ +VALUE +rb_mul(int argc, VALUE *argv, VALUE self) +{ + VALUE val, scale, dest; + if (rb_scan_args(argc, argv, "11", &val, &scale) < 2) + scale = rb_float_new(1.0); + dest = new_mat_kind_object(cvGetSize(CVARR(self)), self); + try { + if (rb_obj_is_kind_of(val, rb_klass)) + cvMul(CVARR(self), CVARR(val), CVARR(dest), NUM2DBL(scale)); + else { + CvScalar scl = VALUE_TO_CVSCALAR(val); + VALUE mat = new_object(cvGetSize(CVARR(self)), cvGetElemType(CVARR(self))); + cvSet(CVARR(mat), scl); + cvMul(CVARR(self), CVARR(mat), CVARR(dest), NUM2DBL(scale)); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Calculates the product of two arrays. + * dst = self * val + shiftvec + * + * @overload mat_mul(val, shiftvec = nil) + * @param val [CvMat] Array to multiply + * @param shiftvec [CvMat] Optional translation vector + * @return [CvMat] Result array + * @opencv_func cvMatMul + * @opencv_func cvMatMulAdd + */ +VALUE +rb_mat_mul(int argc, VALUE *argv, VALUE self) +{ + VALUE val, shiftvec, dest; + rb_scan_args(argc, argv, "11", &val, &shiftvec); + CvArr* self_ptr = CVARR(self); + dest = new_mat_kind_object(cvGetSize(self_ptr), self); + try { + if (NIL_P(shiftvec)) + cvMatMul(self_ptr, CVARR_WITH_CHECK(val), CVARR(dest)); + else + cvMatMulAdd(self_ptr, CVARR_WITH_CHECK(val), CVARR_WITH_CHECK(shiftvec), CVARR(dest)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Performs per-element division of two arrays or a scalar by an array. + * + * @overload div(val, scale = 1.0) + * @param val [CvMat, CvScalar] Array or scalar to divide + * @param scale [Number] Scale factor + * @return [CvMat] Result array + * @opencv_func cvDiv + */ +VALUE +rb_div(int argc, VALUE *argv, VALUE self) +{ + VALUE val, scale; + if (rb_scan_args(argc, argv, "11", &val, &scale) < 2) + scale = rb_float_new(1.0); + CvArr* self_ptr = CVARR(self); + VALUE dest = Qnil; + try { + dest = new_mat_kind_object(cvGetSize(self_ptr), self); + if (rb_obj_is_kind_of(val, rb_klass)) + cvDiv(self_ptr, CVARR(val), CVARR(dest), NUM2DBL(scale)); + else { + CvScalar scl = VALUE_TO_CVSCALAR(val); + VALUE mat = new_mat_kind_object(cvGetSize(self_ptr), self); + CvArr* mat_ptr = CVARR(mat); + cvSet(mat_ptr, scl); + cvDiv(self_ptr, mat_ptr, CVARR(dest), NUM2DBL(scale)); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Computes the weighted sum of two arrays. + * This function calculates the weighted sum of two arrays as follows: + * dst(I) = src1(I) * alpha + src2(I) * beta + gamma + * + * @overload add_weighted(src1, alpha, src2, beta, gamma) + * @param src1 [CvMat] The first source array. + * @param alpha [Number] Weight for the first array elements. + * @param src2 [CvMat] The second source array. + * @param beta [Number] Weight for the second array elements. + * @param gamma [Number] Scalar added to each sum. + * @return [CvMat] Result array + * @opencv_func cvAddWeighted + */ +VALUE +rb_add_weighted(VALUE klass, VALUE src1, VALUE alpha, VALUE src2, VALUE beta, VALUE gamma) +{ + CvArr* src1_ptr = CVARR_WITH_CHECK(src1); + VALUE dst = new_mat_kind_object(cvGetSize(src1_ptr), src1); + try { + cvAddWeighted(src1_ptr, NUM2DBL(alpha), + CVARR_WITH_CHECK(src2), NUM2DBL(beta), + NUM2DBL(gamma), CVARR(dst)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dst; +} + +/* + * Calculates the per-element bit-wise conjunction of two arrays or an array and a scalar. + * + * @overload and(val, mask = nil) + * @param val [CvMat, CvScalar] Array or scalar to calculate bit-wise conjunction + * @param mask [CvMat] Optional operation mask, 8-bit single channel array, that specifies + * elements of the destination array to be changed. + * @return [CvMat] Result array + * @opencv_func cvAnd + * @opencv_func cvAndS + */ +VALUE +rb_and(int argc, VALUE *argv, VALUE self) +{ + VALUE val, mask, dest; + rb_scan_args(argc, argv, "11", &val, &mask); + dest = copy(self); + try { + if (rb_obj_is_kind_of(val, rb_klass)) + cvAnd(CVARR(self), CVARR(val), CVARR(dest), MASK(mask)); + else + cvAndS(CVARR(self), VALUE_TO_CVSCALAR(val), CVARR(dest), MASK(mask)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Calculates the per-element bit-wise disjunction of two arrays or an array and a scalar. + * + * @overload or(val, mask = nil) + * @param val [CvMat, CvScalar] Array or scalar to calculate bit-wise disjunction + * @param mask [CvMat] Optional operation mask, 8-bit single channel array, that specifies + * elements of the destination array to be changed. + * @return [CvMat] Result array + * @opencv_func cvOr + * @opencv_func cvOrS + */ +VALUE +rb_or(int argc, VALUE *argv, VALUE self) +{ + VALUE val, mask, dest; + rb_scan_args(argc, argv, "11", &val, &mask); + dest = copy(self); + try { + if (rb_obj_is_kind_of(val, rb_klass)) + cvOr(CVARR(self), CVARR(val), CVARR(dest), MASK(mask)); + else + cvOrS(CVARR(self), VALUE_TO_CVSCALAR(val), CVARR(dest), MASK(mask)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Calculates the per-element bit-wise "exclusive or" operation on two arrays or an array and a scalar. + * + * @overload xor(val, mask = nil) + * @param val [CvMat, CvScalar] Array or scalar to calculate bit-wise xor operation. + * @param mask [CvMat] Optional operation mask, 8-bit single channel array, that specifies + * elements of the destination array to be changed. + * @return [CvMat] Result array + * @opencv_func cvXor + * @opencv_func cvXorS + */ +VALUE +rb_xor(int argc, VALUE *argv, VALUE self) +{ + VALUE val, mask, dest; + rb_scan_args(argc, argv, "11", &val, &mask); + dest = copy(self); + try { + if (rb_obj_is_kind_of(val, rb_klass)) + cvXor(CVARR(self), CVARR(val), CVARR(dest), MASK(mask)); + else + cvXorS(CVARR(self), VALUE_TO_CVSCALAR(val), CVARR(dest), MASK(mask)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Returns an array which elements are bit-wise invertion of source array. + * + * @overload not + * @return [CvMat] Result array + * @opencv_func cvNot + */ +VALUE +rb_not(VALUE self) +{ + return rb_not_bang(copy(self)); +} + +/* + * Inverts every bit of an array. + * + * @overload not! + * @return [CvMat] Result array + * @opencv_func cvNot + */ +VALUE +rb_not_bang(VALUE self) +{ + try { + cvNot(CVARR(self), CVARR(self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +VALUE +rb_cmp_internal(VALUE self, VALUE val, int operand) +{ + CvArr* self_ptr = CVARR(self); + VALUE dest = new_mat_kind_object(cvGetSize(self_ptr), self, CV_8U, 1); + try { + if (rb_obj_is_kind_of(val, rb_klass)) + cvCmp(self_ptr, CVARR(val), CVARR(dest), operand); + else if (CV_MAT_CN(cvGetElemType(self_ptr)) == 1 && rb_obj_is_kind_of(val, rb_cNumeric)) + cvCmpS(self_ptr, NUM2DBL(val), CVARR(dest), operand); + else { + VALUE mat = new_mat_kind_object(cvGetSize(CVARR(self)), self); + cvSet(CVARR(mat), VALUE_TO_CVSCALAR(val)); + cvCmp(self_ptr, CVARR(mat), CVARR(dest), operand); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Performs the per-element comparison "equal" of two arrays or an array and scalar value. + * + * @overload eq(val) + * @param val [CvMat, CvScalar, Number] Array, scalar or number to compare + * @return [CvMat] Result array + * @opencv_func cvCmp + * @opencv_func cvCmpS + */ +VALUE +rb_eq(VALUE self, VALUE val) +{ + return rb_cmp_internal(self, val, CV_CMP_EQ); +} + +/* + * Performs the per-element comparison "greater than" of two arrays or an array and scalar value. + * + * @overload gt(val) + * @param val [CvMat, CvScalar, Number] Array, scalar or number to compare + * @return [CvMat] Result array + * @opencv_func cvCmp + * @opencv_func cvCmpS + */ +VALUE +rb_gt(VALUE self, VALUE val) +{ + return rb_cmp_internal(self, val, CV_CMP_GT); +} + +/* + * Performs the per-element comparison "greater than or equal" of two arrays or an array and scalar value. + * + * @overload ge(val) + * @param val [CvMat, CvScalar, Number] Array, scalar or number to compare + * @return [CvMat] Result array + * @opencv_func cvCmp + * @opencv_func cvCmpS + */ +VALUE +rb_ge(VALUE self, VALUE val) +{ + return rb_cmp_internal(self, val, CV_CMP_GE); +} + +/* + * Performs the per-element comparison "less than" of two arrays or an array and scalar value. + * + * @overload lt(val) + * @param val [CvMat, CvScalar, Number] Array, scalar or number to compare + * @return [CvMat] Result array + * @opencv_func cvCmp + * @opencv_func cvCmpS + */ +VALUE +rb_lt(VALUE self, VALUE val) +{ + return rb_cmp_internal(self, val, CV_CMP_LT); +} + +/* + * Performs the per-element comparison "less than or equal" of two arrays or an array and scalar value. + * + * @overload le(val) + * @param val [CvMat, CvScalar, Number] Array, scalar or number to compare + * @return [CvMat] Result array + * @opencv_func cvCmp + * @opencv_func cvCmpS + */ +VALUE +rb_le(VALUE self, VALUE val) +{ + return rb_cmp_internal(self, val, CV_CMP_LE); +} + +/* + * Performs the per-element comparison "not equal" of two arrays or an array and scalar value. + * + * @overload ne(val) + * @param val [CvMat, CvScalar, Number] Array, scalar or number to compare + * @return [CvMat] Result array + * @opencv_func cvCmp + * @opencv_func cvCmpS + */ +VALUE +rb_ne(VALUE self, VALUE val) +{ + return rb_cmp_internal(self, val, CV_CMP_NE); +} + +/* + * Checks if array elements lie between the elements of two other arrays. + * + * @overload in_range(min, max) + * @param min [CvMat, CvScalar] Inclusive lower boundary array or a scalar. + * @param max [CvMat, CvScalar] Inclusive upper boundary array or a scalar. + * @return [CvMat] Result array + * @opencv_func cvInRange + * @opencv_func cvInRangeS + */ +VALUE +rb_in_range(VALUE self, VALUE min, VALUE max) +{ + CvArr* self_ptr = CVARR(self); + CvSize size = cvGetSize(self_ptr); + VALUE dest = new_object(size, CV_8UC1); + try { + if (rb_obj_is_kind_of(min, rb_klass) && rb_obj_is_kind_of(max, rb_klass)) + cvInRange(self_ptr, CVARR(min), CVARR(max), CVARR(dest)); + else if (rb_obj_is_kind_of(min, rb_klass)) { + VALUE tmp = new_object(size, cvGetElemType(self_ptr)); + cvSet(CVARR(tmp), VALUE_TO_CVSCALAR(max)); + cvInRange(self_ptr, CVARR(min), CVARR(tmp), CVARR(dest)); + } + else if (rb_obj_is_kind_of(max, rb_klass)) { + VALUE tmp = new_object(size, cvGetElemType(self_ptr)); + cvSet(CVARR(tmp), VALUE_TO_CVSCALAR(min)); + cvInRange(self_ptr, CVARR(tmp), CVARR(max), CVARR(dest)); + } + else + cvInRangeS(self_ptr, VALUE_TO_CVSCALAR(min), VALUE_TO_CVSCALAR(max), CVARR(dest)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Computes the per-element absolute difference between two arrays or between an array and a scalar. + * + * @overload abs_diff(val) + * @param val [CvMat, CvScalar] Array or scalar to compute absolute difference + * @return [CvMat] Result array + * @opencv_func cvAbsDiff + * @opencv_func cvAbsDiffS + */ +VALUE +rb_abs_diff(VALUE self, VALUE val) +{ + CvArr* self_ptr = CVARR(self); + VALUE dest = new_mat_kind_object(cvGetSize(self_ptr), self); + try { + if (rb_obj_is_kind_of(val, rb_klass)) + cvAbsDiff(self_ptr, CVARR(val), CVARR(dest)); + else + cvAbsDiffS(self_ptr, CVARR(dest), VALUE_TO_CVSCALAR(val)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Normalizes the norm or value range of an array. + * + * @overload normalize(alpha = 1.0, beta = 0.0, norm_type = NORM_L2, dtype = -1, mask = nil) + * @param alpha [Number] Norm value to normalize to or the lower range boundary + * in case of the range normalization. + * @param beta [Number] Upper range boundary in case of the range normalization. + * It is not used for the norm normalization. + * @param norm_type [Integer] Normalization type. + * @param dtype [Integer] when negative, the output array has the same type as src; + * otherwise, it has the same number of channels as src and the depth + * @param mask [CvMat] Optional operation mask. + * @return [CvMat] Normalized array. + * @opencv_func cv::normalize + */ +VALUE +rb_normalize(int argc, VALUE *argv, VALUE self) +{ + VALUE alpha_val, beta_val, norm_type_val, dtype_val, mask_val; + rb_scan_args(argc, argv, "05", &alpha_val, &beta_val, &norm_type_val, &dtype_val, &mask_val); + + double alpha = NIL_P(alpha_val) ? 1.0 : NUM2DBL(alpha_val); + double beta = NIL_P(beta_val) ? 0.0 : NUM2DBL(beta_val); + int norm_type = NIL_P(norm_type_val) ? cv::NORM_L2 : NUM2INT(norm_type_val); + int dtype = NIL_P(dtype_val) ? -1 : NUM2INT(dtype_val); + VALUE dst; + + try { + cv::Mat self_mat(CVMAT(self)); + cv::Mat dst_mat; + + if (NIL_P(mask_val)) { + cv::normalize(self_mat, dst_mat, alpha, beta, norm_type, dtype); + } + else { + cv::Mat mask(MASK(mask_val)); + cv::normalize(self_mat, dst_mat, alpha, beta, norm_type, dtype, mask); + } + dst = new_mat_kind_object(cvGetSize(CVARR(self)), self, dst_mat.depth(), dst_mat.channels()); + + CvMat tmp = dst_mat; + cvCopy(&tmp, CVMAT(dst)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return dst; +} + +/* + * Counts non-zero array elements. + * + * @overload count_non_zero + * @return [Integer] The number of non-zero elements. + * @opencv_func cvCountNonZero + */ +VALUE +rb_count_non_zero(VALUE self) +{ + int n = 0; + try { + n = cvCountNonZero(CVARR(self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return INT2NUM(n); +} + +/* + * Calculates the sum of array elements. + * + * @overload sum + * @return [CvScalar] The sum of array elements. + * @opencv_func cvSum + */ +VALUE +rb_sum(VALUE self) +{ + CvScalar sum; + try { + sum = cvSum(CVARR(self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return cCvScalar::new_object(sum); +} + +/* + * Calculates an average (mean) of array elements. + * @overload avg(mask = nil) + * @param mask [CvMat] Optional operation mask. + * @return [CvScalar] The average of array elements. + * @opencv_func cvAvg + */ +VALUE +rb_avg(int argc, VALUE *argv, VALUE self) +{ + VALUE mask; + rb_scan_args(argc, argv, "01", &mask); + CvScalar avg; + try { + avg = cvAvg(CVARR(self), MASK(mask)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return cCvScalar::new_object(avg); +} + +/* + * Calculates a mean and standard deviation of array elements. + * @overload avg_sdv(mask = nil) + * @param mask [CvMat] Optional operation mask. + * @return [Array] [mean, stddev], + * where mean is the computed mean value and stddev is the computed standard deviation. + * @opencv_func cvAvgSdv + */ +VALUE +rb_avg_sdv(int argc, VALUE *argv, VALUE self) +{ + VALUE mask, mean, std_dev; + rb_scan_args(argc, argv, "01", &mask); + mean = cCvScalar::new_object(); + std_dev = cCvScalar::new_object(); + try { + cvAvgSdv(CVARR(self), CVSCALAR(mean), CVSCALAR(std_dev), MASK(mask)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_ary_new3(2, mean, std_dev); +} + +/* + * Calculates a standard deviation of array elements. + * @overload sdv(mask = nil) + * @param mask [CvMat] Optional operation mask. + * @return [CvScalar] The standard deviation of array elements. + * @opencv_func cvAvgSdv + */ +VALUE +rb_sdv(int argc, VALUE *argv, VALUE self) +{ + VALUE mask, std_dev; + rb_scan_args(argc, argv, "01", &mask); + std_dev = cCvScalar::new_object(); + try { + cvAvgSdv(CVARR(self), NULL, CVSCALAR(std_dev), MASK(mask)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return std_dev; +} + +/* + * Finds the global minimum and maximum in an array. + * + * @overload min_max_loc(mask = nil) + * @param mask [CvMat] Optional mask used to select a sub-array. + * @return [Array] [min_val, max_val, min_loc, max_loc], where + * min_val, max_val are minimum, maximum values as Number and + * min_loc, max_loc are minimum, maximum locations as CvPoint, respectively. + * @opencv_func cvMinMaxLoc + */ +VALUE +rb_min_max_loc(int argc, VALUE *argv, VALUE self) +{ + VALUE mask, min_loc, max_loc; + double min_val = 0.0, max_val = 0.0; + rb_scan_args(argc, argv, "01", &mask); + min_loc = cCvPoint::new_object(); + max_loc = cCvPoint::new_object(); + try { + cvMinMaxLoc(CVARR(self), &min_val, &max_val, CVPOINT(min_loc), CVPOINT(max_loc), MASK(mask)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_ary_new3(4, rb_float_new(min_val), rb_float_new(max_val), min_loc, max_loc); +} + +/* + * Calculates an absolute array norm, an absolute difference norm, or a relative difference norm. + * + * @overload norm(src1, src2=nil, norm_type=NORM_L2, mask=nil) + * @param src1 [CvMat] First input array. + * @param src2 [CvMat] Second input array of the same size and the same type as src1. + * @param norm_type [Integer] Type of the norm. + * @param mask [CvMat] Optional operation mask; it must have the same size as src1 and CV_8UC1 type. + * @return [Number] The norm of two arrays. + * @opencv_func cvNorm + * @scope class + */ +VALUE +rb_norm(int argc, VALUE *argv, VALUE self) +{ + VALUE src1, src2, norm_type_val, mask_val; + rb_scan_args(argc, argv, "13", &src1, &src2, &norm_type_val, &mask_val); + + CvMat *src1_ptr = NULL; + CvMat *src2_ptr = NULL; + int norm_type = NIL_P(norm_type_val) ? cv::NORM_L2 : NUM2INT(norm_type_val); + CvMat *mask = NULL; + double norm = 0.0; + + try { + src1_ptr = CVMAT_WITH_CHECK(src1); + if (!NIL_P(src2)) { + src2_ptr = CVMAT_WITH_CHECK(src2); + } + if (!NIL_P(mask_val)) { + mask = CVMAT_WITH_CHECK(mask_val); + } + norm = cvNorm(src1_ptr, src2_ptr, norm_type, mask); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return DBL2NUM(norm); +} + +/* + * Calculates the dot product of two arrays in Euclidean metrics. + * + * @overload dot_product(mat) + * @param mat [CvMat] An array to calculate the dot product. + * @return [Number] The dot product of two arrays. + * @opencv_func cvDotProduct + */ +VALUE +rb_dot_product(VALUE self, VALUE mat) +{ + double result = 0.0; + try { + result = cvDotProduct(CVARR(self), CVARR_WITH_CHECK(mat)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_float_new(result); +} + +/* + * Calculates the cross product of two 3D vectors. + * + * @overload cross_product(mat) + * @param mat [CvMat] A vector to calculate the cross product. + * @return [CvMat] The cross product of two vectors. + * @opencv_func cvCrossProduct + */ +VALUE +rb_cross_product(VALUE self, VALUE mat) +{ + CvArr* self_ptr = CVARR(self); + VALUE dest = Qnil; + try { + dest = new_mat_kind_object(cvGetSize(self_ptr), self); + cvCrossProduct(self_ptr, CVARR_WITH_CHECK(mat), CVARR(dest)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Performs the matrix transformation of every array element. + * + * @overload transform(transmat, shiftvec = nil) + * @param transmat [CvMat] Transformation 2x2 or 2x3 floating-point matrix. + * @param shiftvec [CvMat] Optional translation vector. + * @return [CvMat] Transformed array. + * @opencv_func cvTransform + */ +VALUE +rb_transform(int argc, VALUE *argv, VALUE self) +{ + VALUE transmat, shiftvec; + rb_scan_args(argc, argv, "11", &transmat, &shiftvec); + CvArr* self_ptr = CVARR(self); + VALUE dest = Qnil; + try { + dest = new_mat_kind_object(cvGetSize(self_ptr), self); + cvTransform(self_ptr, CVARR(dest), CVMAT_WITH_CHECK(transmat), + NIL_P(shiftvec) ? NULL : CVMAT_WITH_CHECK(shiftvec)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Performs the perspective matrix transformation of vectors. + * + * @overload perspective_transform(mat) + * @param mat [CvMat] 3x3 or 4x4 floating-point transformation matrix. + * @return [CvMat] Transformed vector. + * @opencv_func cvPerspectiveTransform + */ +VALUE +rb_perspective_transform(VALUE self, VALUE mat) +{ + CvArr* self_ptr = CVARR(self); + VALUE dest = Qnil; + try { + dest = new_mat_kind_object(cvGetSize(self_ptr), self); + cvPerspectiveTransform(self_ptr, CVARR(dest), CVMAT_WITH_CHECK(mat)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Calculates the product of a matrix and its transposition. + * + * This function calculates the product of self and its transposition: + * if :order = 0 + * dst = scale * (self - delta) * (self - delta)T + * otherwise + * dst = scale * (self - delta)T * (self - delta) + * + * @overload mul_transposed(options) + * @param options [Hash] Options + * @option options [Integer] :order (0) Flag specifying the multiplication ordering, should be 0 or 1. + * @option options [CvMat] :delta (nil) Optional delta matrix subtracted from source before the multiplication. + * @option options [Number] :scale (1.0) Optional scale factor for the matrix product. + * @return [CvMat] Result array. + * @opencv_func cvMulTransposed + */ +VALUE +rb_mul_transposed(int argc, VALUE *argv, VALUE self) +{ + VALUE options = Qnil; + VALUE _delta = Qnil, _scale = Qnil, _order = Qnil; + + if (rb_scan_args(argc, argv, "01", &options) > 0) { + Check_Type(options, T_HASH); + _delta = LOOKUP_HASH(options, "delta"); + _scale = LOOKUP_HASH(options, "scale"); + _order = LOOKUP_HASH(options, "order"); + } + + CvArr* delta = NIL_P(_delta) ? NULL : CVARR_WITH_CHECK(_delta); + double scale = NIL_P(_scale) ? 1.0 : NUM2DBL(_scale); + int order = NIL_P(_order) ? 0 : NUM2INT(_order); + CvArr* self_ptr = CVARR(self); + VALUE dest = new_mat_kind_object(cvGetSize(self_ptr), self); + try { + cvMulTransposed(self_ptr, CVARR(dest), order, delta, scale); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return dest; +} + + +/* + * Returns the trace of a matrix. + * + * @overload trace + * @return [CvScalar] The trace of a matrix. + * @opencv_func cvTrace + */ +VALUE +rb_trace(VALUE self) +{ + CvScalar scalar; + try { + scalar = cvTrace(CVARR(self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return cCvScalar::new_object(scalar); +} + +/* + * Transposes a matrix. + * + * @overload transpose + * @return [CvMat] Transposed matrix. + * @opencv_func cvTranspose + */ +VALUE +rb_transpose(VALUE self) +{ + CvMat* self_ptr = CVMAT(self); + VALUE dest = new_mat_kind_object(cvSize(self_ptr->rows, self_ptr->cols), self); + try { + cvTranspose(self_ptr, CVARR(dest)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Returns the determinant of a square floating-point matrix. + * + * @overload det + * @return [Number] The determinant of the matrix. + * @opencv_func cvDet + */ +VALUE +rb_det(VALUE self) +{ + double det = 0.0; + try { + det = cvDet(CVARR(self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_float_new(det); +} + +/* + * Finds inverse or pseudo-inverse of matrix. + * + * @overload invert(inversion_method = :lu) + * @param inversion_method [Symbol] Inversion method. + * * :lu - Gaussian elimincation with optimal pivot element chose. + * * :svd - Singular value decomposition(SVD) method. + * * :svd_sym - SVD method for a symmetric positively-defined matrix. + * @return [Number] Inverse or pseudo-inverse of matrix. + * @opencv_func cvInvert + */ +VALUE +rb_invert(int argc, VALUE *argv, VALUE self) +{ + VALUE symbol; + rb_scan_args(argc, argv, "01", &symbol); + int method = CVMETHOD("INVERSION_METHOD", symbol, CV_LU); + VALUE dest = Qnil; + CvArr* self_ptr = CVARR(self); + try { + dest = new_mat_kind_object(cvGetSize(self_ptr), self); + cvInvert(self_ptr, CVARR(dest), method); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Solves one or more linear systems or least-squares problems. + * + * @overload solve(src1, src2, inversion_method = :lu) + * @param src1 [CvMat] Input matrix on the left-hand side of the system. + * @param src2 [CvMat] Input matrix on the right-hand side of the system. + * @param inversion_method [Symbol] Inversion method. + * * :lu - Gaussian elimincation with optimal pivot element chose. + * * :svd - Singular value decomposition(SVD) method. + * * :svd_sym - SVD method for a symmetric positively-defined matrix. + * @return [Number] Output solution. + * @scope class + * @opencv_func cvSolve + */ +VALUE +rb_solve(int argc, VALUE *argv, VALUE self) +{ + VALUE src1, src2, symbol; + rb_scan_args(argc, argv, "21", &src1, &src2, &symbol); + VALUE dest = Qnil; + CvArr* src2_ptr = CVARR_WITH_CHECK(src2); + try { + dest = new_mat_kind_object(cvGetSize(src2_ptr), src2); + cvSolve(CVARR_WITH_CHECK(src1), src2_ptr, CVARR(dest), CVMETHOD("INVERSION_METHOD", symbol, CV_LU)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Performs SVD of a matrix + * @overload svd(flag = 0) + * @param flag [Integer] Operation flags. + * * CV_SVD_MODIFY_A - Use the algorithm to modify the decomposed matrix. It can save space and speed up processing. + * * CV_SVD_U_T - Indicate that only a vector of singular values w is to be computed, while u and v will be set to empty matrices. + * * CV_SVD_V_T - When the matrix is not square, by default the algorithm produces u and v matrices of sufficiently large size for the further A reconstruction. If, however, CV_SVD_V_T flag is specified, u and v will be full-size square orthogonal matrices. + * @return [Array] Array of the computed values [w, u, v], where + * * w - Computed singular values + * * u - Computed left singular vectors + * * v - Computed right singular vectors + * @opencv_func cvSVD + */ +VALUE +rb_svd(int argc, VALUE *argv, VALUE self) +{ + VALUE _flag = Qnil; + int flag = 0; + if (rb_scan_args(argc, argv, "01", &_flag) > 0) { + flag = NUM2INT(_flag); + } + + CvMat* self_ptr = CVMAT(self); + VALUE w = new_mat_kind_object(cvSize(self_ptr->cols, self_ptr->rows), self); + + int rows = 0; + int cols = 0; + if (flag & CV_SVD_U_T) { + rows = MIN(self_ptr->rows, self_ptr->cols); + cols = self_ptr->rows; + } + else { + rows = self_ptr->rows; + cols = MIN(self_ptr->rows, self_ptr->cols); + } + VALUE u = new_mat_kind_object(cvSize(cols, rows), self); + + if (flag & CV_SVD_V_T) { + rows = MIN(self_ptr->rows, self_ptr->cols); + cols = self_ptr->cols; + } + else { + rows = self_ptr->cols; + cols = MIN(self_ptr->rows, self_ptr->cols); + } + VALUE v = new_mat_kind_object(cvSize(cols, rows), self); + + cvSVD(self_ptr, CVARR(w), CVARR(u), CVARR(v), flag); + + return rb_ary_new3(3, w, u, v); +} + +/* + * Computes eigenvalues and eigenvectors of symmetric matrix. + * self should be symmetric square matrix. self is modified during the processing. + * + * @overload eigenvv + * @return [Array] Array of [eigenvalues, eigenvectors] + * @opencv_func cvEigenVV + */ +VALUE +rb_eigenvv(int argc, VALUE *argv, VALUE self) +{ + VALUE epsilon, lowindex, highindex; + rb_scan_args(argc, argv, "03", &epsilon, &lowindex, &highindex); + double eps = (NIL_P(epsilon)) ? 0.0 : NUM2DBL(epsilon); + int lowidx = (NIL_P(lowindex)) ? -1 : NUM2INT(lowindex); + int highidx = (NIL_P(highindex)) ? -1 : NUM2INT(highindex); + VALUE eigen_vectors = Qnil, eigen_values = Qnil; + CvArr* self_ptr = CVARR(self); + try { + CvSize size = cvGetSize(self_ptr); + int type = cvGetElemType(self_ptr); + eigen_vectors = new_object(size, type); + eigen_values = new_object(size.height, 1, type); + // NOTE: eps, lowidx, highidx are ignored in the current OpenCV implementation. + cvEigenVV(self_ptr, CVARR(eigen_vectors), CVARR(eigen_values), eps, lowidx, highidx); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_ary_new3(2, eigen_vectors, eigen_values); +} + + +/* + * Performs a forward or inverse Discrete Fourier transform of a 1D or 2D floating-point array. + * + * @overload dft(flags = CV_DXT_FORWARD, nonzero_rows = 0) + * @param flags [Integer] transformation flags, representing a combination of the following values: + * * CV_DXT_FORWARD - Performs a 1D or 2D transform. + * * CV_DXT_INVERSE - Performs an inverse 1D or 2D transform instead of the default forward transform. + * * CV_DXT_SCALE - Scales the result: divide it by the number of array elements. + * Normally, it is combined with CV_DXT_INVERSE. + * * CV_DXT_INV_SCALE - CV_DXT_INVERSE + CV_DXT_SCALE + * @param nonzero_rows [Integer] when the parameter is not zero, the function assumes that only + * the first nonzero_rows rows of the input array (CV_DXT_INVERSE is not set) + * or only the first nonzero_rows of the output array (CV_DXT_INVERSE is set) contain non-zeros. + * @return [CvMat] Output array + * @opencv_func cvDFT + */ +VALUE +rb_dft(int argc, VALUE *argv, VALUE self) +{ + VALUE flag_value, nonzero_row_value; + rb_scan_args(argc, argv, "02", &flag_value, &nonzero_row_value); + + int flags = NIL_P(flag_value) ? CV_DXT_FORWARD : NUM2INT(flag_value); + int nonzero_rows = NIL_P(nonzero_row_value) ? 0 : NUM2INT(nonzero_row_value); + CvArr* self_ptr = CVARR(self); + VALUE dest = Qnil; + try { + dest = new_mat_kind_object(cvGetSize(self_ptr), self); + cvDFT(self_ptr, CVARR(dest), flags, nonzero_rows); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Performs forward or inverse Discrete Cosine Transform(DCT) of 1D or 2D floating-point array. + * + * @overload dct(flags = CV_DXT_FORWARD) + * @param flags [Integer] transformation flags, representing a combination of the following values: + * * CV_DXT_FORWARD - Performs a 1D or 2D transform. + * * CV_DXT_INVERSE - Performs an inverse 1D or 2D transform instead of the default forward transform. + * * CV_DXT_ROWS - Performs a forward or inverse transform of every individual row of the input matrix. + * This flag enables you to transform multiple vectors simultaneously and can be used to decrease + * the overhead (which is sometimes several times larger than the processing itself) to perform 3D + * and higher-dimensional transforms and so forth. + * @return [CvMat] Output array + * @opencv_func cvDCT + */ +VALUE +rb_dct(int argc, VALUE *argv, VALUE self) +{ + VALUE flag_value; + rb_scan_args(argc, argv, "01", &flag_value); + + int flags = NIL_P(flag_value) ? CV_DXT_FORWARD : NUM2INT(flag_value); + CvArr* self_ptr = CVARR(self); + VALUE dest = Qnil; + try { + dest = new_mat_kind_object(cvGetSize(self_ptr), self); + cvDCT(self_ptr, CVARR(dest), flags); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Returns an image that is drawn a line segment connecting two points. + * + * @overload line(p1, p2, options = nil) + * @param p1 [CvPoint] First point of the line segment. + * @param p2 [CvPoint] Second point of the line segment. + * @param options [Hash] Drawing options + * @option options [CvScalar] :color Line color. + * @option options [Integer] :thickness Line thickness. + * @option options [Integer] :line_type Type of the line. + * * 8 - 8-connected line. + * * 4 - 4-connected line. + * * CV_AA - Antialiased line. + * @option options [Integer] :shift Number of fractional bits in the point coordinates. + * @return [CvMat] Output image + * @opencv_func cvLine + */ +VALUE +rb_line(int argc, VALUE *argv, VALUE self) +{ + return rb_line_bang(argc, argv, rb_clone(self)); +} + +/* + * Draws a line segment connecting two points. + * + * @overload line!(p1, p2, options = nil) + * @param p1 [CvPoint] First point of the line segment. + * @param p2 [CvPoint] Second point of the line segment. + * @param options [Hash] Drawing options + * @option options [CvScalar] :color Line color. + * @option options [Integer] :thickness Line thickness. + * @option options [Integer] :line_type Type of the line. + * * 8 - 8-connected line. + * * 4 - 4-connected line. + * * CV_AA - Antialiased line. + * @option options [Integer] :shift Number of fractional bits in the point coordinates. + * @return [CvMat] self + * @opencv_func (see #line) + */ +VALUE +rb_line_bang(int argc, VALUE *argv, VALUE self) +{ + VALUE p1, p2, drawing_option; + rb_scan_args(argc, argv, "21", &p1, &p2, &drawing_option); + drawing_option = DRAWING_OPTION(drawing_option); + try { + cvLine(CVARR(self), VALUE_TO_CVPOINT(p1), VALUE_TO_CVPOINT(p2), + DO_COLOR(drawing_option), + DO_THICKNESS(drawing_option), + DO_LINE_TYPE(drawing_option), + DO_SHIFT(drawing_option)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Returns an image that is drawn a simple, thick, or filled up-right rectangle. + * + * @overload rectangle(p1, p2, options = nil) + * @param p1 [CvPoint] Vertex of the rectangle. + * @param p2 [CvPoint] Vertex of the rectangle opposite to p1. + * @param options [Hash] Drawing options + * @option options [CvScalar] :color Line color. + * @option options [Integer] :thickness Line thickness. + * @option options [Integer] :line_type Type of the line. + * * 8 - 8-connected line. + * * 4 - 4-connected line. + * * CV_AA - Antialiased line. + * @option options [Integer] :shift Number of fractional bits in the point coordinates. + * @return [CvMat] Output image + * @opencv_func cvRectangle + */ +VALUE +rb_rectangle(int argc, VALUE *argv, VALUE self) +{ + return rb_rectangle_bang(argc, argv, rb_clone(self)); +} + +/* + * Draws a simple, thick, or filled up-right rectangle. + * + * @overload rectangle!(p1, p2, options = nil) + * @param p1 [CvPoint] Vertex of the rectangle. + * @param p2 [CvPoint] Vertex of the rectangle opposite to p1. + * @param options [Hash] Drawing options + * @option options [CvScalar] :color Line color. + * @option options [Integer] :thickness Line thickness. + * @option options [Integer] :line_type Type of the line. + * * 8 - 8-connected line. + * * 4 - 4-connected line. + * * CV_AA - Antialiased line. + * @option options [Integer] :shift Number of fractional bits in the point coordinates. + * @return [CvMat] self + * @opencv_func cvRectangle + */ +VALUE +rb_rectangle_bang(int argc, VALUE *argv, VALUE self) +{ + VALUE p1, p2, drawing_option; + rb_scan_args(argc, argv, "21", &p1, &p2, &drawing_option); + drawing_option = DRAWING_OPTION(drawing_option); + try { + cvRectangle(CVARR(self), VALUE_TO_CVPOINT(p1), VALUE_TO_CVPOINT(p2), + DO_COLOR(drawing_option), + DO_THICKNESS(drawing_option), + DO_LINE_TYPE(drawing_option), + DO_SHIFT(drawing_option)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Returns an image that is drawn a circle + * + * @overload circle(center, radius, options = nil) + * @param center [CvPoint] Center of the circle. + * @param radius [Integer] Radius of the circle. + * @param options [Hash] Drawing options + * @option options [CvScalar] :color Line color. + * @option options [Integer] :thickness Line thickness. + * @option options [Integer] :line_type Type of the line. + * * 8 - 8-connected line. + * * 4 - 4-connected line. + * * CV_AA - Antialiased line. + * @option options [Integer] :shift Number of fractional bits in the point coordinates. + * @return [CvMat] Output image + * @opencv_func cvCircle + */ +VALUE +rb_circle(int argc, VALUE *argv, VALUE self) +{ + return rb_circle_bang(argc, argv, rb_clone(self)); +} + +/* + * Draws a circle + * + * @overload circle!(center, radius, options = nil) + * @param center [CvPoint] Center of the circle. + * @param radius [Integer] Radius of the circle. + * @param options [Hash] Drawing options + * @option options [CvScalar] :color Line color. + * @option options [Integer] :thickness Line thickness. + * @option options [Integer] :line_type Type of the line. + * * 8 - 8-connected line. + * * 4 - 4-connected line. + * * CV_AA - Antialiased line. + * @option options [Integer] :shift Number of fractional bits in the point coordinates. + * @return [CvMat] self + * @opencv_func cvCircle + */ +VALUE +rb_circle_bang(int argc, VALUE *argv, VALUE self) +{ + VALUE center, radius, drawing_option; + rb_scan_args(argc, argv, "21", ¢er, &radius, &drawing_option); + drawing_option = DRAWING_OPTION(drawing_option); + try { + cvCircle(CVARR(self), VALUE_TO_CVPOINT(center), NUM2INT(radius), + DO_COLOR(drawing_option), + DO_THICKNESS(drawing_option), + DO_LINE_TYPE(drawing_option), + DO_SHIFT(drawing_option)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Returns an image that is drawn a simple or thick elliptic arc or fills an ellipse sector. + * + * @overload ellipse(center, axes, angle, start_angle, end_angle, options = nil) + * @param center [CvPoint] Center of the ellipse. + * @param axes [CvSize] Length of the ellipse axes. + * @param angle [Number] Ellipse rotation angle in degrees. + * @param start_angle [Number] Starting angle of the elliptic arc in degrees. + * @param end_angle [Number] Ending angle of the elliptic arc in degrees. + * @param options [Hash] Drawing options + * @option options [CvScalar] :color Line color. + * @option options [Integer] :thickness Line thickness. + * @option options [Integer] :line_type Type of the line. + * * 8 - 8-connected line. + * * 4 - 4-connected line. + * * CV_AA - Antialiased line. + * @option options [Integer] :shift Number of fractional bits in the point coordinates. + * @return [CvMat] Output image + * @opencv_func cvEllipse + */ +VALUE +rb_ellipse(int argc, VALUE *argv, VALUE self) +{ + return rb_ellipse_bang(argc, argv, rb_clone(self)); +} + +/* + * Draws a simple or thick elliptic arc or fills an ellipse sector. + * + * @overload ellipse!(center, axes, angle, start_angle, end_angle, options = nil) + * @param center [CvPoint] Center of the ellipse. + * @param axes [CvSize] Length of the ellipse axes. + * @param angle [Number] Ellipse rotation angle in degrees. + * @param start_angle [Number] Starting angle of the elliptic arc in degrees. + * @param end_angle [Number] Ending angle of the elliptic arc in degrees. + * @param options [Hash] Drawing options + * @option options [CvScalar] :color Line color. + * @option options [Integer] :thickness Line thickness. + * @option options [Integer] :line_type Type of the line. + * * 8 - 8-connected line. + * * 4 - 4-connected line. + * * CV_AA - Antialiased line. + * @option options [Integer] :shift Number of fractional bits in the point coordinates. + * @return [CvMat] self + * @opencv_func cvEllipse + */ +VALUE +rb_ellipse_bang(int argc, VALUE *argv, VALUE self) +{ + VALUE center, axis, angle, start_angle, end_angle, drawing_option; + rb_scan_args(argc, argv, "51", ¢er, &axis, &angle, &start_angle, &end_angle, &drawing_option); + drawing_option = DRAWING_OPTION(drawing_option); + try { + cvEllipse(CVARR(self), VALUE_TO_CVPOINT(center), + VALUE_TO_CVSIZE(axis), + NUM2DBL(angle), NUM2DBL(start_angle), NUM2DBL(end_angle), + DO_COLOR(drawing_option), + DO_THICKNESS(drawing_option), + DO_LINE_TYPE(drawing_option), + DO_SHIFT(drawing_option)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Returns an image that is drawn a simple or thick elliptic arc or fills an ellipse sector. + * + * @overload ellipse_box(box, options = nil) + * @param box [CvBox2D] Alternative ellipse representation via CvBox2D. This means that + * the function draws an ellipse inscribed in the rotated rectangle. + * @param options [Hash] Drawing options + * @option options [CvScalar] :color Line color. + * @option options [Integer] :thickness Line thickness. + * @option options [Integer] :line_type Type of the line. + * * 8 - 8-connected line. + * * 4 - 4-connected line. + * * CV_AA - Antialiased line. + * @option options [Integer] :shift Number of fractional bits in the point coordinates. + * @return [CvMat] Output image + * @opencv_func cvEllipseBox + */ +VALUE +rb_ellipse_box(int argc, VALUE *argv, VALUE self) +{ + return rb_ellipse_box_bang(argc, argv, rb_clone(self)); +} + +/* + * Draws a simple or thick elliptic arc or fills an ellipse sector. + * + * @overload ellipse_box!(box, options = nil) + * @param box [CvBox2D] Alternative ellipse representation via CvBox2D. This means that + * the function draws an ellipse inscribed in the rotated rectangle. + * @param options [Hash] Drawing options + * @option options [CvScalar] :color Line color. + * @option options [Integer] :thickness Line thickness. + * @option options [Integer] :line_type Type of the line. + * * 8 - 8-connected line. + * * 4 - 4-connected line. + * * CV_AA - Antialiased line. + * @option options [Integer] :shift Number of fractional bits in the point coordinates. + * @return [CvMat] self + * @opencv_func cvEllipseBox + */ +VALUE +rb_ellipse_box_bang(int argc, VALUE *argv, VALUE self) +{ + VALUE box, drawing_option; + rb_scan_args(argc, argv, "11", &box, &drawing_option); + drawing_option = DRAWING_OPTION(drawing_option); + try { + cvEllipseBox(CVARR(self), VALUE_TO_CVBOX2D(box), + DO_COLOR(drawing_option), + DO_THICKNESS(drawing_option), + DO_LINE_TYPE(drawing_option), + DO_SHIFT(drawing_option)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Returns an image that is filled the area bounded by one or more polygons. + * + * @overload fill_poly(points, options = nil) + * @param points [Array] Array of polygons where each polygon is represented as an array of points. + * @param options [Hash] Drawing options + * @option options [CvScalar] :color Line color. + * @option options [Integer] :thickness Line thickness. + * @option options [Integer] :line_type Type of the line. + * * 8 - 8-connected line. + * * 4 - 4-connected line. + * * CV_AA - Antialiased line. + * @option options [Integer] :shift Number of fractional bits in the point coordinates. + * @return [CvMat] Output image + * @opencv_func cvFillPoly + */ +VALUE +rb_fill_poly(int argc, VALUE *argv, VALUE self) +{ + return rb_fill_poly_bang(argc, argv, self); +} + +/* + * Fills the area bounded by one or more polygons. + * + * @overload fill_poly!(points, options = nil) + * @param points [Array] Array of polygons where each polygon is represented as an array of points. + * @param options [Hash] Drawing options + * @option options [CvScalar] :color Line color. + * @option options [Integer] :thickness Line thickness. + * @option options [Integer] :line_type Type of the line. + * * 8 - 8-connected line. + * * 4 - 4-connected line. + * * CV_AA - Antialiased line. + * @option options [Integer] :shift Number of fractional bits in the point coordinates. + * @return [CvMat] self + * @opencv_func cvFillPoly + */ +VALUE +rb_fill_poly_bang(int argc, VALUE *argv, VALUE self) +{ + VALUE polygons, drawing_option; + VALUE points; + int i, j; + int num_polygons; + int *num_points; + CvPoint **p; + + rb_scan_args(argc, argv, "11", &polygons, &drawing_option); + Check_Type(polygons, T_ARRAY); + drawing_option = DRAWING_OPTION(drawing_option); + num_polygons = RARRAY_LEN(polygons); + num_points = RB_ALLOC_N(int, num_polygons); + + p = RB_ALLOC_N(CvPoint*, num_polygons); + for (j = 0; j < num_polygons; ++j) { + points = rb_ary_entry(polygons, j); + Check_Type(points, T_ARRAY); + num_points[j] = RARRAY_LEN(points); + p[j] = RB_ALLOC_N(CvPoint, num_points[j]); + for (i = 0; i < num_points[j]; ++i) { + p[j][i] = VALUE_TO_CVPOINT(rb_ary_entry(points, i)); + } + } + try { + cvFillPoly(CVARR(self), p, num_points, num_polygons, + DO_COLOR(drawing_option), + DO_LINE_TYPE(drawing_option), + DO_SHIFT(drawing_option)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Returns an image that is filled a convex polygon. + * + * @overload fill_convex_poly(points, options = nil) + * @param points [Array] Polygon vertices. + * @param options [Hash] Drawing options + * @option options [CvScalar] :color Line color. + * @option options [Integer] :thickness Line thickness. + * @option options [Integer] :line_type Type of the line. + * * 8 - 8-connected line. + * * 4 - 4-connected line. + * * CV_AA - Antialiased line. + * @option options [Integer] :shift Number of fractional bits in the point coordinates. + * @return [CvMat] Output image + * @opencv_func cvFillConvexPoly + */ +VALUE +rb_fill_convex_poly(int argc, VALUE *argv, VALUE self) +{ + return rb_fill_convex_poly_bang(argc, argv, rb_clone(self)); +} + +/* + * Fills a convex polygon. + * + * @overload fill_convex_poly!(points, options = nil) + * @param points [Array] Polygon vertices. + * @param options [Hash] Drawing options + * @option options [CvScalar] :color Line color. + * @option options [Integer] :thickness Line thickness. + * @option options [Integer] :line_type Type of the line. + * * 8 - 8-connected line. + * * 4 - 4-connected line. + * * CV_AA - Antialiased line. + * @option options [Integer] :shift Number of fractional bits in the point coordinates. + * @return [CvMat] self + * @opencv_func cvFillConvexPoly + */ +VALUE +rb_fill_convex_poly_bang(int argc, VALUE *argv, VALUE self) +{ + VALUE points, drawing_option; + int i, num_points; + CvPoint *p; + + rb_scan_args(argc, argv, "11", &points, &drawing_option); + Check_Type(points, T_ARRAY); + drawing_option = DRAWING_OPTION(drawing_option); + num_points = RARRAY_LEN(points); + p = RB_ALLOC_N(CvPoint, num_points); + for (i = 0; i < num_points; ++i) + p[i] = VALUE_TO_CVPOINT(rb_ary_entry(points, i)); + + try { + cvFillConvexPoly(CVARR(self), p, num_points, + DO_COLOR(drawing_option), + DO_LINE_TYPE(drawing_option), + DO_SHIFT(drawing_option)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Returns an image that is drawn several polygonal curves. + * + * @overload poly_line(points, options = nil) + * @param points [Array] Array of polygonal curves. + * @param options [Hash] Drawing options + * @option options [CvScalar] :color Line color. + * @option options [Integer] :thickness Line thickness. + * @option options [Integer] :line_type Type of the line. + * * 8 - 8-connected line. + * * 4 - 4-connected line. + * * CV_AA - Antialiased line. + * @option options [Boolean] :is_closed + * Indicates whether the polylines must be drawn closed. + * If closed, the method draws the line from the last vertex + * of every contour to the first vertex. + * @option options [Integer] :shift Number of fractional bits in the point coordinates. + * @return [CvMat] Output image + * @opencv_func cvPolyLine + */ +VALUE +rb_poly_line(int argc, VALUE *argv, VALUE self) +{ + return rb_poly_line_bang(argc, argv, rb_clone(self)); +} + +/* + * Draws several polygonal curves. + * + * @overload poly_line!(points, options = nil) + * @param points [Array] Array of polygonal curves. + * @param options [Hash] Drawing options + * @option options [CvScalar] :color Line color. + * @option options [Integer] :thickness Line thickness. + * @option options [Integer] :line_type Type of the line. + * * 8 - 8-connected line. + * * 4 - 4-connected line. + * * CV_AA - Antialiased line. + * @option options [Boolean] :is_closed + * Indicates whether the polylines must be drawn closed. + * If closed, the method draws the line from the last vertex + * of every contour to the first vertex. + * @option options [Integer] :shift Number of fractional bits in the point coordinates. + * @return [CvMat] self + * @opencv_func cvPolyLine + */ +VALUE +rb_poly_line_bang(int argc, VALUE *argv, VALUE self) +{ + VALUE polygons, drawing_option; + VALUE points; + int i, j; + int num_polygons; + int *num_points; + CvPoint **p; + + rb_scan_args(argc, argv, "11", &polygons, &drawing_option); + Check_Type(polygons, T_ARRAY); + drawing_option = DRAWING_OPTION(drawing_option); + num_polygons = RARRAY_LEN(polygons); + num_points = RB_ALLOC_N(int, num_polygons); + p = RB_ALLOC_N(CvPoint*, num_polygons); + + for (j = 0; j < num_polygons; ++j) { + points = rb_ary_entry(polygons, j); + Check_Type(points, T_ARRAY); + num_points[j] = RARRAY_LEN(points); + p[j] = RB_ALLOC_N(CvPoint, num_points[j]); + for (i = 0; i < num_points[j]; ++i) { + p[j][i] = VALUE_TO_CVPOINT(rb_ary_entry(points, i)); + } + } + + try { + cvPolyLine(CVARR(self), p, num_points, num_polygons, + DO_IS_CLOSED(drawing_option), + DO_COLOR(drawing_option), + DO_THICKNESS(drawing_option), + DO_LINE_TYPE(drawing_option), + DO_SHIFT(drawing_option)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return self; +} + + +/* + * Returns an image which is drawn a text string. + * + * @overload put_text(text, org, font, color = CvColor::Black) + * @param text [String] Text string to be drawn. + * @param org [CvPoint] Bottom-left corner of the text string in the image. + * @param font [CvFont] CvFont object. + * @param color [CvScalar] Text color. + * @return [CvMat] Output image + * @opencv_func cvPutText + */ +VALUE +rb_put_text(int argc, VALUE* argv, VALUE self) +{ + return rb_put_text_bang(argc, argv, rb_clone(self)); +} + +/* + * Draws a text string. + * + * @overload put_text!(text, org, font, color = CvColor::Black) + * @param text [String] Text string to be drawn. + * @param org [CvPoint] Bottom-left corner of the text string in the image. + * @param font [CvFont] CvFont object. + * @param color [CvScalar] Text color. + * @return [CvMat] self + * @opencv_func cvPutText + */ +VALUE +rb_put_text_bang(int argc, VALUE* argv, VALUE self) +{ + VALUE _text, _point, _font, _color; + rb_scan_args(argc, argv, "31", &_text, &_point, &_font, &_color); + CvScalar color = NIL_P(_color) ? CV_RGB(0, 0, 0) : VALUE_TO_CVSCALAR(_color); + try { + cvPutText(CVARR(self), StringValueCStr(_text), VALUE_TO_CVPOINT(_point), + CVFONT_WITH_CHECK(_font), color); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Calculates the first, second, third, or mixed image derivatives using an extended Sobel operator. + * + * @overload sobel(xorder, yorder, aperture_size = 3) + * @param xorder [Integer] Order of the derivative x. + * @param yorder [Integer] Order of the derivative y. + * @param aperture_size [Integer] Size of the extended Sobel kernel; it must be 1, 3, 5, or 7. + * @return [CvMat] Output image. + * @opencv_func cvSovel + */ +VALUE +rb_sobel(int argc, VALUE *argv, VALUE self) +{ + VALUE xorder, yorder, aperture_size, dest; + if (rb_scan_args(argc, argv, "21", &xorder, &yorder, &aperture_size) < 3) + aperture_size = INT2FIX(3); + CvMat* self_ptr = CVMAT(self); + switch(CV_MAT_DEPTH(self_ptr->type)) { + case CV_8U: + dest = new_mat_kind_object(cvGetSize(self_ptr), self, CV_16S, 1); + break; + case CV_32F: + dest = new_mat_kind_object(cvGetSize(self_ptr), self, CV_32F, 1); + break; + default: + rb_raise(rb_eArgError, "source depth should be CV_8U or CV_32F."); + break; + } + + try { + cvSobel(self_ptr, CVARR(dest), NUM2INT(xorder), NUM2INT(yorder), NUM2INT(aperture_size)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Calculates the Laplacian of an image. + * + * @overload laplace(aperture_size = 3) + * @param aperture_size [Integer] Aperture size used to compute the second-derivative filters. + * The size must be positive and odd. + * @return Output image. + * @opencv_func cvLaplace + */ +VALUE +rb_laplace(int argc, VALUE *argv, VALUE self) +{ + VALUE aperture_size, dest; + if (rb_scan_args(argc, argv, "01", &aperture_size) < 1) + aperture_size = INT2FIX(3); + CvMat* self_ptr = CVMAT(self); + switch(CV_MAT_DEPTH(self_ptr->type)) { + case CV_8U: + dest = new_mat_kind_object(cvGetSize(self_ptr), self, CV_16S, 1); + break; + case CV_32F: + dest = new_mat_kind_object(cvGetSize(self_ptr), self, CV_32F, 1); + break; + default: + rb_raise(rb_eArgError, "source depth should be CV_8U or CV_32F."); + } + + try { + cvLaplace(self_ptr, CVARR(dest), NUM2INT(aperture_size)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Finds edges in an image using the [Canny86] algorithm. + * + * Canny86: J. Canny. A Computational Approach to Edge Detection, IEEE Trans. on Pattern Analysis + * and Machine Intelligence, 8(6), pp. 679-698 (1986). + * + * @overload canny(thresh1, thresh2, aperture_size = 3) + * @param thresh1 [Number] First threshold for the hysteresis procedure. + * @param thresh2 [Number] Second threshold for the hysteresis procedure. + * @param aperture_size [Integer] Aperture size for the sobel operator. + * @return [CvMat] Output edge map + * @opencv_func cvCanny + */ +VALUE +rb_canny(int argc, VALUE *argv, VALUE self) +{ + VALUE thresh1, thresh2, aperture_size; + if (rb_scan_args(argc, argv, "21", &thresh1, &thresh2, &aperture_size) < 3) + aperture_size = INT2FIX(3); + CvArr* self_ptr = CVARR(self); + VALUE dest = new_mat_kind_object(cvGetSize(self_ptr), self); + + try { + cvCanny(self_ptr, CVARR(dest), NUM2INT(thresh1), NUM2INT(thresh2), NUM2INT(aperture_size)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Calculates a feature map for corner detection. + * + * @overload pre_corner_detect(aperture_size = 3) + * @param aperture_size [Integer] Aperture size for the sobel operator. + * @return [CvMat] Output image + * @opencv_func cvPreCornerDetect + */ +VALUE +rb_pre_corner_detect(int argc, VALUE *argv, VALUE self) +{ + VALUE aperture_size, dest = Qnil; + if (rb_scan_args(argc, argv, "01", &aperture_size) < 1) + aperture_size = INT2FIX(3); + + CvArr *self_ptr = CVARR(self); + try { + dest = new_object(cvGetSize(self_ptr), CV_MAKETYPE(CV_32F, 1)); + cvPreCornerDetect(self_ptr, CVARR(dest), NUM2INT(aperture_size)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Calculates eigenvalues and eigenvectors of image blocks for corner detection. + * + * @overload corner_eigenvv(block_size, aperture_size = 3) + * @param block_size [Integer] Neighborhood size. + * @param aperture_size [Integer] Aperture parameter for the sobel operator. + * @return [CvMat] Result array. + * @opencv_func cvCornerEigenValsAndVecs + */ +VALUE +rb_corner_eigenvv(int argc, VALUE *argv, VALUE self) +{ + VALUE block_size, aperture_size, dest; + if (rb_scan_args(argc, argv, "11", &block_size, &aperture_size) < 2) + aperture_size = INT2FIX(3); + CvMat* self_ptr = CVMAT(self); + dest = new_object(cvSize(self_ptr->cols * 6, self_ptr->rows), CV_MAKETYPE(CV_32F, 1)); + try { + cvCornerEigenValsAndVecs(self_ptr, CVARR(dest), NUM2INT(block_size), NUM2INT(aperture_size)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Calculates the minimal eigenvalue of gradient matrices for corner detection. + * + * @overload corner_min_eigen_val(block_size, aperture_size = 3) + * @param block_size [Integer] Neighborhood size. + * @param aperture_size [Integer] Aperture parameter for the sobel operator. + * @return [CvMat] Result array. + * @opencv_func cvCornerMinEigenVal + */ +VALUE +rb_corner_min_eigen_val(int argc, VALUE *argv, VALUE self) +{ + VALUE block_size, aperture_size, dest; + if (rb_scan_args(argc, argv, "11", &block_size, &aperture_size) < 2) + aperture_size = INT2FIX(3); + CvArr* self_ptr = CVARR(self); + dest = new_object(cvGetSize(self_ptr), CV_MAKETYPE(CV_32F, 1)); + try { + cvCornerMinEigenVal(self_ptr, CVARR(dest), NUM2INT(block_size), NUM2INT(aperture_size)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Harris edge detector. + * + * @overload corner_harris(block_size, aperture_size = 3, k = 0.04) + * @param block_size [Integer] Neighborhood size. + * @param aperture_size [Integer] Aperture parameter for the sobel operator. + * @param k [Number] Harris detector free parameter. + * @return [CvMat] The Harris detector responses. + * @opencv_func cvCornerHarris + */ +VALUE +rb_corner_harris(int argc, VALUE *argv, VALUE self) +{ + VALUE block_size, aperture_size, k, dest; + rb_scan_args(argc, argv, "12", &block_size, &aperture_size, &k); + CvArr* self_ptr = CVARR(self); + dest = new_object(cvGetSize(self_ptr), CV_MAKETYPE(CV_32F, 1)); + try { + cvCornerHarris(self_ptr, CVARR(dest), NUM2INT(block_size), IF_INT(aperture_size, 3), IF_DBL(k, 0.04)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Finds the positions of internal corners of the chessboard. + * + * @overload find_chessboard_corners(pattern_size, flag = CV_CALIB_CB_ADAPTIVE_THRESH) + * @param pattern_size [CvSize] Number of inner corners per a chessboard row and column. + * @param flags [Integer] Various operation flags that can be zero or a combination of the following values. + * * CV_CALIB_CB_ADAPTIVE_THRESH + * * Use adaptive thresholding to convert the image to black and white, rather than + * a fixed threshold level (computed from the average image brightness). + * * CV_CALIB_CB_NORMALIZE_IMAGE + * * Normalize the image gamma with CvMat#equalize_hist() before applying fixed or adaptive thresholding. + * * CV_CALIB_CB_FILTER_QUADS + * * Use additional criteria (like contour area, perimeter, square-like shape) to + * filter out false quads extracted at the contour retrieval stage. + * * CALIB_CB_FAST_CHECK + * * Run a fast check on the image that looks for chessboard corners, and shortcut the call + * if none is found. This can drastically speed up the call in the degenerate condition + * when no chessboard is observed. + * @return [Array, Boolean>] An array which includes the positions of internal corners + * of the chessboard, and a parameter indicating whether the complete board was found or not. + * @opencv_func cvFindChessboardCorners + * @example + * mat = CvMat.load('chessboard.jpg', 1) + * gray = mat.BGR2GRAY + * pattern_size = CvSize.new(4, 4) + * corners, found = gray.find_chessboard_corners(pattern_size, CV_CALIB_CB_ADAPTIVE_THRESH) + * + * if found + * corners = gray.find_corner_sub_pix(corners, CvSize.new(3, 3), CvSize.new(-1, -1), CvTermCriteria.new(20, 0.03)) + * end + * + * result = mat.draw_chessboard_corners(pattern_size, corners, found) + * w = GUI::Window.new('Result') + * w.show result + * GUI::wait_key + */ +VALUE +rb_find_chessboard_corners(int argc, VALUE *argv, VALUE self) +{ + VALUE pattern_size_val, flag_val; + rb_scan_args(argc, argv, "11", &pattern_size_val, &flag_val); + + int flag = NIL_P(flag_val) ? CV_CALIB_CB_ADAPTIVE_THRESH : NUM2INT(flag_val); + CvSize pattern_size = VALUE_TO_CVSIZE(pattern_size_val); + CvPoint2D32f* corners = RB_ALLOC_N(CvPoint2D32f, pattern_size.width * pattern_size.height); + int num_found_corners = 0; + int pattern_was_found = 0; + try { + pattern_was_found = cvFindChessboardCorners(CVARR(self), pattern_size, corners, &num_found_corners, flag); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + VALUE found_corners = rb_ary_new2(num_found_corners); + for (int i = 0; i < num_found_corners; i++) { + rb_ary_store(found_corners, i, cCvPoint2D32f::new_object(corners[i])); + } + + VALUE found = (pattern_was_found > 0) ? Qtrue : Qfalse; + return rb_assoc_new(found_corners, found); +} + +/* + * Refines the corner locations. + * + * @overload find_corner_sub_pix(corners, win_size, zero_zone, criteria) + * @param corners [Array] Initial coordinates of the input corners. + * @param win_size [CvSize] Half of the side length of the search window. + * @param zero_zone [CvSize] Half of the size of the dead region in the middle of the search zone over + * which the summation in the formula below is not done. + * @param criteria [CvTermCriteria] Criteria for termination of the iterative process of corner refinement. + * @return [Array] Refined corner coordinates. + * @opencv_func cvFindCornerSubPix + */ +VALUE +rb_find_corner_sub_pix(VALUE self, VALUE corners, VALUE win_size, VALUE zero_zone, VALUE criteria) +{ + Check_Type(corners, T_ARRAY); + int count = RARRAY_LEN(corners); + CvPoint2D32f* corners_buff = RB_ALLOC_N(CvPoint2D32f, count); + VALUE* corners_ptr = RARRAY_PTR(corners); + + for (int i = 0; i < count; i++) { + corners_buff[i] = *(CVPOINT2D32F(corners_ptr[i])); + } + + try { + cvFindCornerSubPix(CVARR(self), corners_buff, count, VALUE_TO_CVSIZE(win_size), + VALUE_TO_CVSIZE(zero_zone), VALUE_TO_CVTERMCRITERIA(criteria)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + VALUE refined_corners = rb_ary_new2(count); + for (int i = 0; i < count; i++) { + rb_ary_store(refined_corners, i, cCvPoint2D32f::new_object(corners_buff[i])); + } + + return refined_corners; +} + +/* + * Determines strong corners on an image. + * + * @overload good_features_to_track(quality_level, min_distance, good_features_to_track_option = {}) + * @param quality_level [Number] Parameter characterizing the minimal accepted quality of image corners. + * The parameter value is multiplied by the best corner quality measure, which is the minimal eigenvalue + * or the Harris function response. + * @param min_distance [Number] Minimum possible Euclidean distance between the returned corners. + * @param good_features_to_track_option [Hash] Options. + * @option good_features_to_track_option [CvMat] :mask (nil) Optional region of interest. + * If the image is not empty (it needs to have the type CV_8UC1 and the same size as image), + * it specifies the region in which the corners are detected. + * @option good_features_to_track_option [Integer] :block_size (3) Size of an average block for computing + * a derivative covariation matrix over each pixel neighborhood. + * @option good_features_to_track_option [Boolean] :use_harris (false) Parameter indicating whether + * to use a Harris detector. + * @option good_features_to_track_option [Number] :k (0.04) Free parameter of the Harris detector. + * @return [Array] Output vector of detected corners. + * @opencv_func cvGoodFeaturesToTrack + */ +VALUE +rb_good_features_to_track(int argc, VALUE *argv, VALUE self) +{ + VALUE quality_level, min_distance, good_features_to_track_option; + rb_scan_args(argc, argv, "21", &quality_level, &min_distance, &good_features_to_track_option); + good_features_to_track_option = GOOD_FEATURES_TO_TRACK_OPTION(good_features_to_track_option); + int np = GF_MAX(good_features_to_track_option); + if (np <= 0) + rb_raise(rb_eArgError, "option :max should be positive value."); + + CvMat *self_ptr = CVMAT(self); + CvPoint2D32f *p32 = (CvPoint2D32f*)rb_cvAlloc(sizeof(CvPoint2D32f) * np); + int type = CV_MAKETYPE(CV_32F, 1); + CvMat* eigen = rb_cvCreateMat(self_ptr->rows, self_ptr->cols, type); + CvMat* tmp = rb_cvCreateMat(self_ptr->rows, self_ptr->cols, type); + try { + cvGoodFeaturesToTrack(self_ptr, &eigen, &tmp, p32, &np, NUM2DBL(quality_level), NUM2DBL(min_distance), + GF_MASK(good_features_to_track_option), + GF_BLOCK_SIZE(good_features_to_track_option), + GF_USE_HARRIS(good_features_to_track_option), + GF_K(good_features_to_track_option)); + } + catch (cv::Exception& e) { + if (eigen != NULL) + cvReleaseMat(&eigen); + if (tmp != NULL) + cvReleaseMat(&tmp); + if (p32 != NULL) + cvFree(&p32); + raise_cverror(e); + } + VALUE corners = rb_ary_new2(np); + for (int i = 0; i < np; ++i) + rb_ary_store(corners, i, cCvPoint2D32f::new_object(p32[i])); + cvFree(&p32); + cvReleaseMat(&eigen); + cvReleaseMat(&tmp); + return corners; +} + +/* + * Retrieves a pixel rectangle from an image with sub-pixel accuracy. + * + * @overload rect_sub_pix(center, size = self.size) + * @param center [CvPoint2D32f] Floating point coordinates of the center of the extracted rectangle within + * the source image. The center must be inside the image. + * @param size [CvSize] Size of the extracted patch. + * @return [CvMat] Extracted patch that has the size size and the same number of channels as self. + * @opencv_func cvGetRectSubPix + */ +VALUE +rb_rect_sub_pix(int argc, VALUE *argv, VALUE self) +{ + VALUE center, size; + VALUE dest = Qnil; + CvSize _size; + CvArr* self_ptr = CVARR(self); + try { + if (rb_scan_args(argc, argv, "11", ¢er, &size) < 2) + _size = cvGetSize(self_ptr); + else + _size = VALUE_TO_CVSIZE(size); + dest = new_mat_kind_object(_size, self); + cvGetRectSubPix(self_ptr, CVARR(dest), VALUE_TO_CVPOINT2D32F(center)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Applies an affine transformation to an image. + * + * @overload quadrangle_sub_pix(map_matrix, size = self.size) + * @param map_matrix [CvMat] 2x3 transformation matrix. + * @param size [CvSize] Size of the output image. + * @return [CvMat] Output image that has the size size and the same type as self. + * @opencv_func cvGetQuadrangleSubPix + * @note CvMat#quadrangle_sub_pix is similar to CvMat#warp_affine, but the outliers are + * extrapolated using replication border mode. + */ +VALUE +rb_quadrangle_sub_pix(int argc, VALUE *argv, VALUE self) +{ + VALUE map_matrix, size; + VALUE dest = Qnil; + CvSize _size; + CvArr* self_ptr = CVARR(self); + try { + if (rb_scan_args(argc, argv, "11", &map_matrix, &size) < 2) + _size = cvGetSize(self_ptr); + else + _size = VALUE_TO_CVSIZE(size); + dest = new_mat_kind_object(_size, self); + cvGetQuadrangleSubPix(self_ptr, CVARR(dest), CVMAT_WITH_CHECK(map_matrix)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Resizes an image. + * + * @overload resize(size, interpolation = :linear) + * @param size [CvSize] Output image size. + * @param interpolation [Symbol] Interpolation method: + * * CV_INTER_NN - A nearest-neighbor interpolation + * * CV_INTER_LINEAR - A bilinear interpolation (used by default) + * * CV_INTER_AREA - Resampling using pixel area relation. It may be a preferred method for + * image decimation, as it gives moire'-free results. But when the image is zoomed, + * it is similar to the :nn method. + * * CV_INTER_CUBIC - A bicubic interpolation over 4x4 pixel neighborhood + * * CV_INTER_LANCZOS4 - A Lanczos interpolation over 8x8 pixel neighborhood + * @return [CvMat] Output image. + * @opencv_func cvResize + */ +VALUE +rb_resize(int argc, VALUE *argv, VALUE self) +{ + VALUE size, interpolation; + rb_scan_args(argc, argv, "11", &size, &interpolation); + VALUE dest = new_mat_kind_object(VALUE_TO_CVSIZE(size), self); + int method = NIL_P(interpolation) ? CV_INTER_LINEAR : NUM2INT(interpolation); + + try { + cvResize(CVARR(self), CVARR(dest), method); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Applies an affine transformation to an image. + * + * @overload warp_affine(map_matrix, flags = CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS, fillval = 0) + * @param map_matrix [CvMat] 2x3 transformation matrix. + * @param flags [Integer] Combination of interpolation methods (#see resize) and the optional + * flag WARP_INVERSE_MAP that means that map_matrix is the inverse transformation. + * @return [CvMat] Output image that has the size size and the same type as self. + * @param fillval [Number, CvScalar] Value used in case of a constant border. + * @opencv_func cvWarpAffine + */ +VALUE +rb_warp_affine(int argc, VALUE *argv, VALUE self) +{ + VALUE map_matrix, flags_val, fill_value; + VALUE dest = Qnil; + if (rb_scan_args(argc, argv, "12", &map_matrix, &flags_val, &fill_value) < 3) + fill_value = INT2FIX(0); + CvArr* self_ptr = CVARR(self); + int flags = NIL_P(flags_val) ? (CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS) : NUM2INT(flags_val); + try { + dest = new_mat_kind_object(cvGetSize(self_ptr), self); + cvWarpAffine(self_ptr, CVARR(dest), CVMAT_WITH_CHECK(map_matrix), + flags, VALUE_TO_CVSCALAR(fill_value)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Finds a perspective transformation between two planes. + * + * @overload find_homography(src_points, dst_points, method = :all, ransac_reproj_threshold = 3, get_mask = false) + * @param src_points [CvMat] Coordinates of the points in the original plane. + * @param dst_points [CvMat] Coordinates of the points in the target plane. + * @param method [Symbol] Method used to computed a homography matrix. The following methods are possible: + * * :all - a regular method using all the points + * * :ransac - RANSAC-based robust method + * * :lmeds - Least-Median robust method + * @param ransac_reproj_threshold [Number] Maximum allowed reprojection error to treat a point pair as + * an inlier (used in the RANSAC method only). + * @param get_mask [Boolean] If true, the optional output mask set by + * a robust method (:ransac or :lmeds) is returned additionally. + * @return [CvMat, Array] The perspective transformation H between the source and the destination + * planes in CvMat. + * If method is :ransac or :lmeds and get_mask is true, the output mask + * is also returned in the form of an array [H, output_mask]. + * @scope class + * @opencv_func cvFindHomography + */ +VALUE +rb_find_homography(int argc, VALUE *argv, VALUE self) +{ + VALUE src_points, dst_points, method, ransac_reproj_threshold, get_status; + rb_scan_args(argc, argv, "23", &src_points, &dst_points, &method, &ransac_reproj_threshold, &get_status); + + VALUE homography = new_object(cvSize(3, 3), CV_32FC1); + int _method = CVMETHOD("HOMOGRAPHY_CALC_METHOD", method, 0); + double _ransac_reproj_threshold = NIL_P(ransac_reproj_threshold) ? 0.0 : NUM2DBL(ransac_reproj_threshold); + + if ((_method != 0) && (!NIL_P(get_status)) && IF_BOOL(get_status, 1, 0, 0)) { + CvMat *src = CVMAT_WITH_CHECK(src_points); + int num_points = MAX(src->rows, src->cols); + VALUE status = new_object(cvSize(num_points, 1), CV_8UC1); + try { + cvFindHomography(src, CVMAT_WITH_CHECK(dst_points), CVMAT(homography), + _method, _ransac_reproj_threshold, CVMAT(status)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_assoc_new(homography, status); + } + else { + try { + cvFindHomography(CVMAT(src_points), CVMAT(dst_points), CVMAT(homography), + _method, _ransac_reproj_threshold, NULL); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return homography; + } +} + +/* + * Calculates an affine matrix of 2D rotation. + * + * @overload rotation_matrix2D(center, angle, scale) + * @param center [CvPoint2D32f] Center of the rotation in the source image. + * @param angle [Number] Rotation angle in degrees. Positive values mean counter-clockwise rotation + * (the coordinate origin is assumed to be the top-left corner). + * @param scale [Number] Isotropic scale factor. + * @return [CvMat] The output affine transformation, 2x3 floating-point matrix. + * @scope class + * @opencv_func cv2DRotationMatrix + */ +VALUE +rb_rotation_matrix2D(VALUE self, VALUE center, VALUE angle, VALUE scale) +{ + VALUE map_matrix = new_object(cvSize(3, 2), CV_MAKETYPE(CV_32F, 1)); + try { + cv2DRotationMatrix(VALUE_TO_CVPOINT2D32F(center), NUM2DBL(angle), NUM2DBL(scale), CVMAT(map_matrix)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return map_matrix; +} + +/* + * Calculates a perspective transform from four pairs of the corresponding points. + * + * @overload get_perspective_transform(src, dst) + * @param src [Array] Coordinates of quadrangle vertices in the source image. + * @param dst [Array] Coordinates of the corresponding quadrangle vertices in the destination image. + * @return [CvMat] Map matrix + * @scope class + * @opencv_func cvGetPerspectiveTransform + */ +VALUE +rb_get_perspective_transform(VALUE self, VALUE source, VALUE dest) +{ + Check_Type(source, T_ARRAY); + Check_Type(dest, T_ARRAY); + + int count = RARRAY_LEN(source); + + CvPoint2D32f* source_buff = RB_ALLOC_N(CvPoint2D32f, count); + CvPoint2D32f* dest_buff = RB_ALLOC_N(CvPoint2D32f, count); + + for (int i = 0; i < count; i++) { + source_buff[i] = *(CVPOINT2D32F(RARRAY_PTR(source)[i])); + dest_buff[i] = *(CVPOINT2D32F(RARRAY_PTR(dest)[i])); + } + + VALUE map_matrix = new_object(cvSize(3, 3), CV_MAKETYPE(CV_32F, 1)); + + try { + cvGetPerspectiveTransform(source_buff, dest_buff, CVMAT(map_matrix)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return map_matrix; +} + +/* + * Applies a perspective transformation to an image. + * + * @overload warp_perspective(map_matrix, flags = CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS, fillval = 0) + * @param map_matrix [CvMat] 3x3 transformation matrix. + * @param flags [Integer] Combination of interpolation methods (CV_INTER_LINEAR or CV_INTER_NEAREST) + * and the optional flag CV_WARP_INVERSE_MAP, that sets map_matrix as the inverse transformation. + * @param fillval [Number, CvScalar] Value used in case of a constant border. + * @return [CvMat] Output image. + * @opencv_func cvWarpPerspective + */ +VALUE +rb_warp_perspective(int argc, VALUE *argv, VALUE self) +{ + VALUE map_matrix, flags_val, option, fillval; + if (rb_scan_args(argc, argv, "13", &map_matrix, &flags_val, &option, &fillval) < 4) + fillval = INT2FIX(0); + CvArr* self_ptr = CVARR(self); + VALUE dest = Qnil; + int flags = NIL_P(flags_val) ? (CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS) : NUM2INT(flags_val); + try { + dest = new_mat_kind_object(cvGetSize(self_ptr), self); + cvWarpPerspective(self_ptr, CVARR(dest), CVMAT_WITH_CHECK(map_matrix), + flags, VALUE_TO_CVSCALAR(fillval)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Applies a generic geometrical transformation to an image. + * + * @overload remap(mapx, mapy, flags = CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS, fillval = 0) + * @param mapx [CvMat] The first map of either (x,y) points or just x values having the type + * CV_16SC2, CV_32FC1, or CV_32FC2. + * @param mapy [CvMat] The second map of y values having the type CV_16UC1, CV_32FC1, or none + * (empty map if mapx is (x,y) points), respectively. + * @param flags [Integer] Combination of interpolation methods (CV_INTER_LINEAR or CV_INTER_NEAREST) + * and the optional flag CV_WARP_INVERSE_MAP, that sets map_matrix as the inverse transformation. + * @param fillval [Number, CvScalar] Value used in case of a constant border. + * @return [CvMat] Output image. + * @opencv_func cvRemap + */ +VALUE +rb_remap(int argc, VALUE *argv, VALUE self) +{ + VALUE mapx, mapy, flags_val, option, fillval; + if (rb_scan_args(argc, argv, "23", &mapx, &mapy, &flags_val, &option, &fillval) < 5) + fillval = INT2FIX(0); + CvArr* self_ptr = CVARR(self); + VALUE dest = Qnil; + int flags = NIL_P(flags_val) ? (CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS) : NUM2INT(flags_val); + try { + dest = new_mat_kind_object(cvGetSize(self_ptr), self); + cvRemap(self_ptr, CVARR(dest), CVARR_WITH_CHECK(mapx), CVARR_WITH_CHECK(mapy), + flags, VALUE_TO_CVSCALAR(fillval)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Remaps an image to log-polar space. + * + * @overload log_polar(size, center, magnitude, flags = CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS) + * @param size [CvSize] Size of the destination image. + * @param center [CvPoint2D32f] The transformation center; where the output precision is maximal. + * @param magnitude [Number] Magnitude scale parameter. + * @param flags [Integer] A combination of interpolation methods and the following optional flags: + * * CV_WARP_FILL_OUTLIERS - fills all of the destination image pixels. If some of them + * correspond to outliers in the source image, they are set to zero. + * * CV_WARP_INVERSE_MAP - performs inverse transformation. + * @return [CvMat] Destination image. + * @opencv_func cvLogPolar + */ +VALUE +rb_log_polar(int argc, VALUE *argv, VALUE self) +{ + VALUE dst_size, center, m, flags; + rb_scan_args(argc, argv, "31", &dst_size, ¢er, &m, &flags); + int _flags = NIL_P(flags) ? (CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS) : NUM2INT(flags); + VALUE dest = new_mat_kind_object(VALUE_TO_CVSIZE(dst_size), self); + try { + cvLogPolar(CVARR(self), CVARR(dest), VALUE_TO_CVPOINT2D32F(center), NUM2DBL(m), _flags); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * call-seq: + * erode([element = nil, iteration = 1]) -> cvmat + * + * Create erodes image by using arbitrary structuring element. + * element is structuring element used for erosion. + * element should be IplConvKernel. If it is nil, a 3x3 rectangular structuring element is used. + * iterations is number of times erosion is applied. + */ +VALUE +rb_erode(int argc, VALUE *argv, VALUE self) +{ + return rb_erode_bang(argc, argv, rb_clone(self)); +} + +/* + * call-seq: + * erode!([element = nil][,iteration = 1]) -> self + * + * Erodes image by using arbitrary structuring element. + * see also #erode. + */ +VALUE +rb_erode_bang(int argc, VALUE *argv, VALUE self) +{ + VALUE element, iteration; + rb_scan_args(argc, argv, "02", &element, &iteration); + IplConvKernel* kernel = NIL_P(element) ? NULL : IPLCONVKERNEL_WITH_CHECK(element); + try { + cvErode(CVARR(self), CVARR(self), kernel, IF_INT(iteration, 1)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * call-seq: + * dilate([element = nil][,iteration = 1]) -> cvmat + * + * Create dilates image by using arbitrary structuring element. + * element is structuring element used for erosion. + * element should be IplConvKernel. If it is nil, a 3x3 rectangular structuring element is used. + * iterations is number of times erosion is applied. + */ +VALUE +rb_dilate(int argc, VALUE *argv, VALUE self) +{ + return rb_dilate_bang(argc, argv, rb_clone(self)); +} + +/* + * call-seq: + * dilate!([element = nil][,iteration = 1]) -> self + * + * Dilate image by using arbitrary structuring element. + * see also #dilate. + */ +VALUE +rb_dilate_bang(int argc, VALUE *argv, VALUE self) +{ + VALUE element, iteration; + rb_scan_args(argc, argv, "02", &element, &iteration); + IplConvKernel* kernel = NIL_P(element) ? NULL : IPLCONVKERNEL_WITH_CHECK(element); + try { + cvDilate(CVARR(self), CVARR(self), kernel, IF_INT(iteration, 1)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Performs advanced morphological transformations using erosion and dilation as basic operations. + * + * @overload morphology(operation, element = nil, iteration = 1) + * @param operation [Integer] Type of morphological operation. + * * CV_MOP_OPEN - Opening + * * CV_MOP_CLOSE - Closing + * * CV_MOP_GRADIENT - Morphological gradient + * * CV_MOP_TOPHAT - Top hat + * * CV_MOP_BLACKHAT - Black hat + * @param element [IplConvKernel] Structuring element. + * @param iteration [Integer] Number of times erosion and dilation are applied. + * @return [CvMat] Result array + * @opencv_func cvMorphologyEx + */ +VALUE +rb_morphology(int argc, VALUE *argv, VALUE self) +{ + VALUE element, iteration, operation_val; + rb_scan_args(argc, argv, "12", &operation_val, &element, &iteration); + + int operation = CVMETHOD("MORPHOLOGICAL_OPERATION", operation_val, -1); + CvArr* self_ptr = CVARR(self); + CvSize size = cvGetSize(self_ptr); + VALUE dest = new_mat_kind_object(size, self); + IplConvKernel* kernel = NIL_P(element) ? NULL : IPLCONVKERNEL_WITH_CHECK(element); + try { + if (operation == CV_MOP_GRADIENT) { + CvMat* temp = rb_cvCreateMat(size.height, size.width, cvGetElemType(self_ptr)); + cvMorphologyEx(self_ptr, CVARR(dest), temp, kernel, CV_MOP_GRADIENT, IF_INT(iteration, 1)); + cvReleaseMat(&temp); + } + else { + cvMorphologyEx(self_ptr, CVARR(dest), 0, kernel, operation, IF_INT(iteration, 1)); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return dest; +} + +/* + * call-seq: + * smooth_blur_no_scale([p1 = 3, p2 = 3]) -> cvmat + * + * Smooths the image by simple blur with no scaling. + * * 8bit unsigned -> return 16bit unsigned + * * 32bit floating point -> return 32bit floating point + * support single-channel image only. + */ +VALUE +rb_smooth_blur_no_scale(int argc, VALUE *argv, VALUE self) +{ + VALUE p1, p2, dest; + rb_scan_args(argc, argv, "02", &p1, &p2); + CvArr* self_ptr = CVARR(self); + int type = cvGetElemType(self_ptr), dest_type; + switch (CV_MAT_DEPTH(type)) { + case CV_8U: + dest_type = CV_16U; + break; + case CV_32F: + dest_type = CV_32F; + break; + default: + rb_raise(rb_eNotImpError, "unsupport format. (support 8bit unsigned/signed or 32bit floating point only)"); + } + dest = new_mat_kind_object(cvGetSize(self_ptr), self, dest_type, CV_MAT_CN(type)); + cvSmooth(self_ptr, CVARR(dest), CV_BLUR_NO_SCALE, IF_INT(p1, 3), IF_INT(p2, 3)); + return dest; +} + +/* + * call-seq: + * smooth_blur([p1 = 3, p2 = 3]) -> cvmat + * + * Smooths the image by simple blur. + * Summation over a pixel p1 x p2 neighborhood with subsequent scaling by 1 / (p1*p2). + */ +VALUE +rb_smooth_blur(int argc, VALUE *argv, VALUE self) +{ + VALUE p1, p2, dest; + rb_scan_args(argc, argv, "02", &p1, &p2); + CvArr* self_ptr = CVARR(self); + dest = new_mat_kind_object(cvGetSize(self_ptr), self); + cvSmooth(self_ptr, CVARR(dest), CV_BLUR, IF_INT(p1, 3), IF_INT(p2, 3)); + return dest; +} + +/* + * call-seq: + * smooth_gaussian([p1 = 3, p2 = 3, p3 = 0.0, p4 = 0.0]) -> cvmat + * + * Smooths the image by gaussian blur. + * Convolving image with p1 x p2 Gaussian kernel. + * + * p3 may specify Gaussian sigma (standard deviation). + * If it is zero, it is calculated from the kernel size: + * sigma = (n/2 - 1)*0.3 + 0.8, where n = p1 for horizontal kernel, + * n = p2 for vertical kernel. + * + * p4 is in case of non-square Gaussian kernel the parameter. + * It may be used to specify a different (from p3) sigma in the vertical direction. + */ +VALUE +rb_smooth_gaussian(int argc, VALUE *argv, VALUE self) +{ + VALUE p1, p2, p3, p4, dest; + rb_scan_args(argc, argv, "04", &p1, &p2, &p3, &p4); + CvArr* self_ptr = CVARR(self); + dest = new_mat_kind_object(cvGetSize(self_ptr), self); + cvSmooth(self_ptr, CVARR(dest), CV_GAUSSIAN, IF_INT(p1, 3), IF_INT(p2, 3), IF_DBL(p3, 0.0), IF_DBL(p4, 0.0)); + return dest; +} + +/* + * call-seq: + * smooth_median([p1 = 3]) -> cvmat + * + * Smooths the image by median blur. + * Finding median of p1 x p1 neighborhood (i.e. the neighborhood is square). + */ +VALUE +rb_smooth_median(int argc, VALUE *argv, VALUE self) +{ + VALUE p1, dest; + rb_scan_args(argc, argv, "01", &p1); + CvArr* self_ptr = CVARR(self); + dest = new_mat_kind_object(cvGetSize(self_ptr), self); + cvSmooth(self_ptr, CVARR(dest), CV_MEDIAN, IF_INT(p1, 3)); + return dest; +} + +/* + * call-seq: + * smooth_bilateral([p1 = 3][p2 = 3]) -> cvmat + * + * Smooths the image by bilateral filter. + * Applying bilateral 3x3 filtering with color sigma=p1 and space sigma=p2. + */ +VALUE +rb_smooth_bilateral(int argc, VALUE *argv, VALUE self) +{ + VALUE p1, p2, dest; + rb_scan_args(argc, argv, "02", &p1, &p2); + CvArr* self_ptr = CVARR(self); + dest = new_mat_kind_object(cvGetSize(self_ptr), self); + cvSmooth(self_ptr, CVARR(dest), CV_BILATERAL, IF_INT(p1, 3), IF_INT(p2, 3)); + return dest; +} + +/** + * Smooths the image in one of several ways. + * + * @overload smooth(smoothtype, size1 = 3, size2 = 0, sigma1 = 0, sigma2 = 0) + * @param smoothtype [Integer] Type of the smoothing. + * * CV_BLUR_NO_SCALE - linear convolution with size1 x size2 box kernel (all 1's). + * If you want to smooth different pixels with different-size box kernels, + * you can use the integral image that is computed using CvMat#integral. + * * CV_BLUR - linear convolution with size1 x size2 box kernel (all 1's) + * with subsequent scaling by 1 / (size1 x size1). + * * CV_GAUSSIAN - linear convolution with a size1 x size2 Gaussian kernel. + * * CV_MEDIAN - median filter with a size1 x size1 square aperture + * * CV_BILATERAL - bilateral filter with a size1 x size1 square aperture, + * color sigma = sigma1 and spatial sigma = sigma2. + * If size1 = 0, the aperture square side is set to CvMat#round(sigma2 * 1.5) * 2 + 1. + * @param size1 [Integer] The first parameter of the smoothing operation, the aperture width. + * Must be a positive odd number (1, 3, 5, ...) + * @param size2 [Integer] The second parameter of the smoothing operation, the aperture height. + * Ignored by CV_MEDIAN and CV_BILATERAL methods. In the case of simple + * scaled/non-scaled and Gaussian blur if size2 is zero, it is set to size1. + * Otherwise it must be a positive odd number. + * @param sigma1 [Integer] In the case of a Gaussian parameter this parameter may specify + * Gaussian sigma (standard deviation). If it is zero, it is calculated from the kernel size. + * @return [CvMat] The destination image. + * @opencv_func cvSmooth + */ +VALUE +rb_smooth(int argc, VALUE *argv, VALUE self) +{ + VALUE smoothtype, p1, p2, p3, p4; + rb_scan_args(argc, argv, "14", &smoothtype, &p1, &p2, &p3, &p4); + int _smoothtype = CVMETHOD("SMOOTHING_TYPE", smoothtype, -1); + + VALUE (*smooth_func)(int c, VALUE* v, VALUE s); + argc--; + switch (_smoothtype) { + case CV_BLUR_NO_SCALE: + smooth_func = rb_smooth_blur_no_scale; + argc = (argc > 2) ? 2 : argc; + break; + case CV_BLUR: + smooth_func = rb_smooth_blur; + argc = (argc > 2) ? 2 : argc; + break; + case CV_GAUSSIAN: + smooth_func = rb_smooth_gaussian; + break; + case CV_MEDIAN: + smooth_func = rb_smooth_median; + argc = (argc > 1) ? 1 : argc; + break; + case CV_BILATERAL: + smooth_func = rb_smooth_bilateral; + argc = (argc > 2) ? 2 : argc; + break; + default: + smooth_func = rb_smooth_gaussian; + break; + } + VALUE result = Qnil; + try { + result = (*smooth_func)(argc, argv + 1, self); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return result; +} + +/* + * call-seq: + * filter2d(kernel[,anchor]) -> cvmat + * + * Convolves image with the kernel. + * Convolution kernel, single-channel floating point matrix (or same depth of self's). + * If you want to apply different kernels to different channels, + * split the image using CvMat#split into separate color planes and process them individually. + */ +VALUE +rb_filter2d(int argc, VALUE *argv, VALUE self) +{ + VALUE _kernel, _anchor; + rb_scan_args(argc, argv, "11", &_kernel, &_anchor); + CvMat* kernel = CVMAT_WITH_CHECK(_kernel); + CvArr* self_ptr = CVARR(self); + VALUE _dest = Qnil; + try { + _dest = new_mat_kind_object(cvGetSize(self_ptr), self); + cvFilter2D(self_ptr, CVARR(_dest), kernel, NIL_P(_anchor) ? cvPoint(-1,-1) : VALUE_TO_CVPOINT(_anchor)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return _dest; +} + +/* + * call-seq: + * copy_make_border(border_type, size, offset[,value = CvScalar.new(0)]) + * + * Copies image and makes border around it. + * border_type: + * - IPL_BORDER_CONSTANT, :constant + * border is filled with the fixed value, passed as last parameter of the function. + * - IPL_BORDER_REPLICATE, :replicate + * the pixels from the top and bottom rows, the left-most and right-most columns are replicated to fill the border + * size: The destination image size + * offset: Coordinates of the top-left corner (or bottom-left in the case of images with bottom-left origin) of the destination image rectangle. + * value: Value of the border pixels if bordertype is IPL_BORDER_CONSTANT or :constant. + */ +VALUE +rb_copy_make_border(int argc, VALUE *argv, VALUE self) +{ + VALUE border_type, size, offset, value, dest; + rb_scan_args(argc, argv, "31", &border_type, &size, &offset, &value); + dest = new_mat_kind_object(VALUE_TO_CVSIZE(size), self); + + int type = 0; + if (SYMBOL_P(border_type)) { + ID type_id = rb_to_id(border_type); + if (type_id == rb_intern("constant")) + type = IPL_BORDER_CONSTANT; + else if (type_id == rb_intern("replicate")) + type = IPL_BORDER_REPLICATE; + else + rb_raise(rb_eArgError, "Invalid border_type (should be :constant or :replicate)"); + } + else + type = NUM2INT(border_type); + + try { + cvCopyMakeBorder(CVARR(self), CVARR(dest), VALUE_TO_CVPOINT(offset), type, + NIL_P(value) ? cvScalar(0) : VALUE_TO_CVSCALAR(value)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * call-seq: + * integral(need_sqsum = false, need_tilted_sum = false) -> [cvmat, cvmat or nil, cvmat or nil] + * + * Calculates integral images. + * If need_sqsum = true, calculate the integral image for squared pixel values. + * If need_tilted_sum = true, calculate the integral for the image rotated by 45 degrees. + * + * sum(X,Y)=sumxCV_THRESH_BINARY + * and CV_THRESH_BINARY_INV thresholding types. + * @param threshold_type [Integer] Thresholding type + * * CV_THRESH_BINARY + * * CV_THRESH_BINARY_INV + * * CV_THRESH_TRUNC + * * CV_THRESH_TOZERO + * * CV_THRESH_TOZERO_INV + * @return [CvMat] Output array of the same size and type as self. + * @overload threshold(threshold, max_value, threshold_type, use_otsu) + * @param threshold [Number] Threshold value. + * @param max_value [Number] Maximum value to use with the CV_THRESH_BINARY + * and CV_THRESH_BINARY_INV thresholding types. + * @param threshold_type [Integer] Thresholding type + * * CV_THRESH_BINARY + * * CV_THRESH_BINARY_INV + * * CV_THRESH_TRUNC + * * CV_THRESH_TOZERO + * * CV_THRESH_TOZERO_INV + * @param use_otsu [Boolean] Determines the optimal threshold value using the Otsu's algorithm + * @return [Array] Output array and Otsu's threshold. + * @opencv_func cvThreshold + * @example + * mat = CvMat.new(3, 3, CV_8U, 1) + * mat.set_data([1, 2, 3, 4, 5, 6, 7, 8, 9]) + * mat #=> [1, 2, 3, + * 4, 5, 6, + * 7, 8, 9] + * result = mat.threshold(4, 7, CV_THRESH_BINARY) + * result #=> [0, 0, 0, + * 0, 7, 7, + * 7, 7, 7] + */ +VALUE +rb_threshold(int argc, VALUE *argv, VALUE self) +{ + VALUE threshold, max_value, threshold_type, use_otsu; + rb_scan_args(argc, argv, "31", &threshold, &max_value, &threshold_type, &use_otsu); + const int INVALID_TYPE = -1; + int type = CVMETHOD("THRESHOLD_TYPE", threshold_type, INVALID_TYPE); + if (type == INVALID_TYPE) + rb_raise(rb_eArgError, "Invalid threshold type."); + + return rb_threshold_internal(type, threshold, max_value, use_otsu, self); +} + +/* + * Applies an adaptive threshold to an array. + * + * @overload adaptive_threshold(max_value, options) + * @param max_value [Number] Non-zero value assigned to the pixels for which the condition is satisfied. + * @param options [Hash] Threshold option + * @option options [Integer, Symbol] :threshold_type (CV_THRESH_BINARY) Thresholding type; + * must be one of CV_THRESH_BINARY or :binary, CV_THRESH_BINARY_INV or :binary_inv. + * @option options [Integer, Symbol] :adaptive_method (CV_ADAPTIVE_THRESH_MEAN_C) Adaptive thresholding algorithm to use: + * CV_ADAPTIVE_THRESH_MEAN_C or :mean_c, CV_ADAPTIVE_THRESH_GAUSSIAN_C or :gaussian_c. + * @option options [Integer] :block_size (3) The size of a pixel neighborhood that is used to calculate a threshold value + * for the pixel: 3, 5, 7, and so on. + * @option options :param1 [Number] (5) The method-dependent parameter. For the methods CV_ADAPTIVE_THRESH_MEAN_C + * and CV_ADAPTIVE_THRESH_GAUSSIAN_C it is a constant subtracted from the mean or weighted mean, though it may be negative + * @return [CvMat] Destination image of the same size and the same type as self. + * @opencv_func cvAdaptiveThreshold + * @example + * mat = CvMat.new(3, 3, CV_8U, 1) + * mat.set_data([1, 2, 3, 4, 5, 6, 7, 8, 9]) + * mat #=> [1, 2, 3, + * 4, 5, 6, + * 7, 8, 9] + * result = mat.adaptive_threshold(7, threshold_type: CV_THRESH_BINARY, + * adaptive_method: CV_ADAPTIVE_THRESH_MEAN_C, + * block_size: 3, param1: 1) + * result #=> [0, 0, 0, + * 7, 7, 7, + * 7, 7, 7] + */ +VALUE +rb_adaptive_threshold(int argc, VALUE *argv, VALUE self) +{ + VALUE max_value, options; + rb_scan_args(argc, argv, "11", &max_value, &options); + + int threshold_type = CV_THRESH_BINARY; + int adaptive_method = CV_ADAPTIVE_THRESH_MEAN_C; + int block_size = 3; + double param1 = 5; + if (!NIL_P(options)) { + Check_Type(options, T_HASH); + threshold_type = CVMETHOD("THRESHOLD_TYPE", LOOKUP_HASH(options, "threshold_type"), + CV_THRESH_BINARY); + adaptive_method = CVMETHOD("ADAPTIVE_METHOD", LOOKUP_HASH(options, "adaptive_method"), + CV_ADAPTIVE_THRESH_MEAN_C); + VALUE _block_size = LOOKUP_HASH(options, "block_size"); + if (!NIL_P(_block_size)) { + block_size = NUM2INT(_block_size); + } + VALUE _param1 = LOOKUP_HASH(options, "param1"); + if (!NIL_P(_param1)) { + param1 = NUM2INT(_param1); + } + } + CvArr* self_ptr = CVARR(self); + VALUE dst = new_mat_kind_object(cvGetSize(self_ptr), self); + try { + cvAdaptiveThreshold(self_ptr, CVARR(dst), NUM2DBL(max_value), adaptive_method, threshold_type, + block_size, param1); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return dst; +} + +/* + * call-seq: + * pyr_down([filter = :gaussian_5x5]) -> cvmat + * + * Return downsamples image. + * + * This operation performs downsampling step of Gaussian pyramid decomposition. + * First it convolves source image with the specified filter and then downsamples the image + * by rejecting even rows and columns. + * + * note: filter - only :gaussian_5x5 is currently supported. + */ +VALUE +rb_pyr_down(int argc, VALUE *argv, VALUE self) +{ + int filter = CV_GAUSSIAN_5x5; + if (argc > 0) { + VALUE filter_type = argv[0]; + switch (TYPE(filter_type)) { + case T_SYMBOL: + // currently suport CV_GAUSSIAN_5x5 only. + break; + default: + raise_typeerror(filter_type, rb_cSymbol); + } + } + CvArr* self_ptr = CVARR(self); + VALUE dest = Qnil; + try { + CvSize original_size = cvGetSize(self_ptr); + CvSize size = { original_size.width >> 1, original_size.height >> 1 }; + dest = new_mat_kind_object(size, self); + cvPyrDown(self_ptr, CVARR(dest), filter); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * call-seq: + * pyr_up([filter = :gaussian_5x5]) -> cvmat + * + * Return upsamples image. + * + * This operation performs up-sampling step of Gaussian pyramid decomposition. + * First it upsamples the source image by injecting even zero rows and columns and + * then convolves result with the specified filter multiplied by 4 for interpolation. + * So the destination image is four times larger than the source image. + * + * note: filter - only :gaussian_5x5 is currently supported. + */ +VALUE +rb_pyr_up(int argc, VALUE *argv, VALUE self) +{ + VALUE filter_type; + rb_scan_args(argc, argv, "01", &filter_type); + int filter = CV_GAUSSIAN_5x5; + if (argc > 0) { + switch (TYPE(filter_type)) { + case T_SYMBOL: + // currently suport CV_GAUSSIAN_5x5 only. + break; + default: + raise_typeerror(filter_type, rb_cSymbol); + } + } + CvArr* self_ptr = CVARR(self); + VALUE dest = Qnil; + try { + CvSize original_size = cvGetSize(self_ptr); + CvSize size = { original_size.width << 1, original_size.height << 1 }; + dest = new_mat_kind_object(size, self); + cvPyrUp(self_ptr, CVARR(dest), filter); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Fills a connected component with the given color. + * + * @overload flood_fill(seed_point, new_val, lo_diff = CvScalar.new(0), up_diff = CvScalar.new(0), flood_fill_option = nil) + * @param seed_point [CvPoint] Starting point. + * @param new_val [CvScalar] New value of the repainted domain pixels. + * @param lo_diff [CvScalar] Maximal lower brightness/color difference between the currently observed pixel + * and one of its neighbor belong to the component or seed pixel to add the pixel to component. + * In case of 8-bit color images it is packed value. + * @param up_diff [CvScalar] Maximal upper brightness/color difference between the currently observed pixel and + * one of its neighbor belong to the component or seed pixel to add the pixel to component. + * In case of 8-bit color images it is packed value. + * @param flood_fill_option [Hash] + * @option flood_fill_option [Integer] :connectivity (4) + * Connectivity determines which neighbors of a pixel are considered (4 or 8). + * @option flood_fill_option [Boolean] :fixed_range (false) + * If set the difference between the current pixel and seed pixel is considered, otherwise difference between + * neighbor pixels is considered (the range is floating). + * @option flood_fill_option [Boolean] :mask_only (false) + * If set, the function does not fill the image(new_val is ignored), but the fills mask. + * @return [Array] Array of output image, connected component and mask. + * @opencv_func cvFloodFill + */ +VALUE +rb_flood_fill(int argc, VALUE *argv, VALUE self) +{ + return rb_flood_fill_bang(argc, argv, copy(self)); +} + +/* + * Fills a connected component with the given color. + * + * @overload flood_fill!(seed_point, new_val, lo_diff = CvScalar.new(0), up_diff = CvScalar.new(0), flood_fill_option = nil) + * @param (see #flood_fill) + * @return (see #flood_fill) + * @opencv_func (see #flood_fill) + */ +VALUE +rb_flood_fill_bang(int argc, VALUE *argv, VALUE self) +{ + VALUE seed_point, new_val, lo_diff, up_diff, flood_fill_option; + rb_scan_args(argc, argv, "23", &seed_point, &new_val, &lo_diff, &up_diff, &flood_fill_option); + flood_fill_option = FLOOD_FILL_OPTION(flood_fill_option); + int flags = FF_CONNECTIVITY(flood_fill_option); + if (FF_FIXED_RANGE(flood_fill_option)) { + flags |= CV_FLOODFILL_FIXED_RANGE; + } + if (FF_MASK_ONLY(flood_fill_option)) { + flags |= CV_FLOODFILL_MASK_ONLY; + } + CvArr* self_ptr = CVARR(self); + VALUE comp = cCvConnectedComp::new_object(); + VALUE mask = Qnil; + try { + CvSize size = cvGetSize(self_ptr); + // TODO: Change argument format to set mask + mask = new_object(size.height + 2, size.width + 2, CV_MAKETYPE(CV_8U, 1)); + CvMat* mask_ptr = CVMAT(mask); + cvSetZero(mask_ptr); + cvFloodFill(self_ptr, + VALUE_TO_CVPOINT(seed_point), + VALUE_TO_CVSCALAR(new_val), + NIL_P(lo_diff) ? cvScalar(0) : VALUE_TO_CVSCALAR(lo_diff), + NIL_P(up_diff) ? cvScalar(0) : VALUE_TO_CVSCALAR(up_diff), + CVCONNECTEDCOMP(comp), + flags, + mask_ptr); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_ary_new3(3, self, comp, mask); +} + +/* + * Finds contours in binary image. + * + * @overload find_contours(find_contours_options) + * @param find_contours_options [Hash] Options + * @option find_contours_options [Integer] :mode (CV_RETR_LIST) Retrieval mode. + * * CV_RETR_EXTERNAL - retrive only the extreme outer contours + * * CV_RETR_LIST - retrieve all the contours and puts them in the list. + * * CV_RETR_CCOMP - retrieve all the contours and organizes them into two-level hierarchy: + * top level are external boundaries of the components, second level are bounda boundaries of the holes + * * CV_RETR_TREE - retrieve all the contours and reconstructs the full hierarchy of nested contours + * Connectivity determines which neighbors of a pixel are considered. + * @option find_contours_options [Integer] :method (CV_CHAIN_APPROX_SIMPLE) Approximation method. + * * CV_CHAIN_CODE - output contours in the Freeman chain code. All other methods output polygons (sequences of vertices). + * * CV_CHAIN_APPROX_NONE - translate all the points from the chain code into points; + * * CV_CHAIN_APPROX_SIMPLE - compress horizontal, vertical, and diagonal segments, that is, the function leaves only their ending points; + * * CV_CHAIN_APPROX_TC89_L1, CV_CHAIN_APPROX_TC89_KCOS - apply one of the flavors of Teh-Chin chain approximation algorithm. + * @option find_contours_options [CvPoint] :offset (CvPoint.new(0, 0)) Offset, by which every contour point is shifted. + * @return [CvContour, CvChain] Detected contours. If :method is :code, + * returns as CvChain, otherwise CvContour. + * @opencv_func cvFindContours + */ +VALUE +rb_find_contours(int argc, VALUE *argv, VALUE self) +{ + return rb_find_contours_bang(argc, argv, copy(self)); +} + +/* + * Finds contours in binary image. + * + * @overload find_contours!(find_contours_options) + * @param (see #find_contours) + * @return (see #find_contours) + * @opencv_func (see #find_contours) + */ +VALUE +rb_find_contours_bang(int argc, VALUE *argv, VALUE self) +{ + VALUE find_contours_option, klass, element_klass, storage; + rb_scan_args(argc, argv, "01", &find_contours_option); + CvSeq *contour = NULL; + find_contours_option = FIND_CONTOURS_OPTION(find_contours_option); + int mode = FC_MODE(find_contours_option); + int method = FC_METHOD(find_contours_option); + int header_size; + if (method == CV_CHAIN_CODE) { + klass = cCvChain::rb_class(); + element_klass = T_FIXNUM; + header_size = sizeof(CvChain); + } + else { + klass = cCvContour::rb_class(); + element_klass = cCvPoint::rb_class(); + header_size = sizeof(CvContour); + } + storage = cCvMemStorage::new_object(); + + int count = 0; + try { + count = cvFindContours(CVARR(self), CVMEMSTORAGE(storage), &contour, header_size, + mode, method, FC_OFFSET(find_contours_option)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + if (count == 0) + return Qnil; + else + return cCvSeq::new_sequence(klass, contour, element_klass, storage); +} + +/* + * call-seq: + * draw_contours(contour, external_color, hole_color, max_level, options) -> cvmat + * + * Draws contour outlines or interiors in an image. + * + * * contour (CvContour) - Pointer to the first contour + * * external_color (CvScalar) - Color of the external contours + * * hole_color (CvScalar) - Color of internal contours (holes) + * * max_level (Integer) - Maximal level for drawn contours. If 0, only contour is drawn. If 1, the contour and all contours following it on the same level are drawn. If 2, all contours following and all contours one level below the contours are drawn, and so forth. If the value is negative, the function does not draw the contours following after contour but draws the child contours of contour up to the |max_level| - 1 level. + * * options (Hash) - Drawing options. + * * :thickness (Integer) - Thickness of lines the contours are drawn with. If it is negative, the contour interiors are drawn (default: 1). + * * :line_type (Integer or Symbol) - Type of the contour segments, see CvMat#line description (default: 8). + */ +VALUE +rb_draw_contours(int argc, VALUE *argv, VALUE self) +{ + return rb_draw_contours_bang(argc, argv, copy(self)); +} + +/* + * call-seq: + * draw_contours!(contour, external_color, hole_color, max_level, options) -> cvmat + * + * Draws contour outlines or interiors in an image. + * + * see CvMat#draw_contours + */ +VALUE +rb_draw_contours_bang(int argc, VALUE *argv, VALUE self) +{ + VALUE contour, external_color, hole_color, max_level, options; + rb_scan_args(argc, argv, "41", &contour, &external_color, &hole_color, &max_level, &options); + options = DRAWING_OPTION(options); + try { + cvDrawContours(CVARR(self), CVSEQ_WITH_CHECK(contour), VALUE_TO_CVSCALAR(external_color), + VALUE_TO_CVSCALAR(hole_color), NUM2INT(max_level), + DO_THICKNESS(options), DO_LINE_TYPE(options)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * call-seq: + * draw_chessboard_corners(pattern_size, corners, pattern_was_found) -> nil + * + * Returns an image which is rendered the detected chessboard corners. + * + * pattern_size (CvSize) - Number of inner corners per a chessboard row and column. + * corners (Array) - Array of detected corners, the output of CvMat#find_chessboard_corners. + * pattern_was_found (Boolean)- Parameter indicating whether the complete board was found or not. + */ +VALUE +rb_draw_chessboard_corners(VALUE self, VALUE pattern_size, VALUE corners, VALUE pattern_was_found) +{ + return rb_draw_chessboard_corners_bang(copy(self), pattern_size, corners, pattern_was_found); +} + +/* + * call-seq: + * draw_chessboard_corners!(pattern_size, corners, pattern_was_found) -> self + * + * Renders the detected chessboard corners. + * + * pattern_size (CvSize) - Number of inner corners per a chessboard row and column. + * corners (Array) - Array of detected corners, the output of CvMat#find_chessboard_corners. + * pattern_was_found (Boolean)- Parameter indicating whether the complete board was found or not. + */ +VALUE +rb_draw_chessboard_corners_bang(VALUE self, VALUE pattern_size, VALUE corners, VALUE pattern_was_found) +{ + Check_Type(corners, T_ARRAY); + int count = RARRAY_LEN(corners); + CvPoint2D32f* corners_buff = RB_ALLOC_N(CvPoint2D32f, count); + VALUE* corners_ptr = RARRAY_PTR(corners); + for (int i = 0; i < count; i++) { + corners_buff[i] = *(CVPOINT2D32F(corners_ptr[i])); + } + + try { + int found = (pattern_was_found == Qtrue); + cvDrawChessboardCorners(CVARR(self), VALUE_TO_CVSIZE(pattern_size), corners_buff, count, found); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return self; +} + +/* + * call-seq: + * pyr_mean_shift_filtering(sp, sr[,max_level = 1][termcrit = CvTermCriteria.new(5,1)]) -> cvmat + * + * Does meanshift image segmentation. + * + * sp - The spatial window radius. + * sr - The color window radius. + * max_level - Maximum level of the pyramid for the segmentation. + * termcrit - Termination criteria: when to stop meanshift iterations. + * + * This method is implements the filtering stage of meanshift segmentation, + * that is, the output of the function is the filtered "posterized" image with color gradients and fine-grain texture flattened. + * At every pixel (X,Y) of the input image (or down-sized input image, see below) + * the function executes meanshift iterations, that is, the pixel (X,Y) neighborhood in the joint space-color hyperspace is considered: + * {(x,y): X-sp≤x≤X+sp && Y-sp≤y≤Y+sp && ||(R,G,B)-(r,g,b)|| ≤ sr}, + * where (R,G,B) and (r,g,b) are the vectors of color components at (X,Y) and (x,y), + * respectively (though, the algorithm does not depend on the color space used, + * so any 3-component color space can be used instead). + * Over the neighborhood the average spatial value (X',Y') + * and average color vector (R',G',B') are found and they act as the neighborhood center on the next iteration: + * (X,Y)~(X',Y'), (R,G,B)~(R',G',B'). + * After the iterations over, the color components of the initial pixel (that is, the pixel from where the iterations started) + * are set to the final value (average color at the last iteration): + * I(X,Y) <- (R*,G*,B*). + * Then max_level > 0, the gaussian pyramid of max_level+1 levels is built, + * and the above procedure is run on the smallest layer. + * After that, the results are propagated to the larger layer and the iterations are run again + * only on those pixels where the layer colors differ much (>sr) from the lower-resolution layer, + * that is, the boundaries of the color regions are clarified. + * + * Note, that the results will be actually different from the ones obtained by running the meanshift procedure on the whole original image (i.e. when max_level==0). + */ +VALUE +rb_pyr_mean_shift_filtering(int argc, VALUE *argv, VALUE self) +{ + VALUE spatial_window_radius, color_window_radius, max_level, termcrit; + rb_scan_args(argc, argv, "22", &spatial_window_radius, &color_window_radius, &max_level, &termcrit); + CvArr* self_ptr = CVARR(self); + VALUE dest = Qnil; + try { + dest = new_mat_kind_object(cvGetSize(self_ptr), self); + cvPyrMeanShiftFiltering(self_ptr, CVARR(dest), + NUM2DBL(spatial_window_radius), + NUM2DBL(color_window_radius), + IF_INT(max_level, 1), + NIL_P(termcrit) ? cvTermCriteria(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 5, 1) + : VALUE_TO_CVTERMCRITERIA(termcrit)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * Performs a marker-based image segmentation using the watershed algorithm. + * + * @overload watershed(markers) + * @param markers [CvMat] Input 32-bit single-channel image of markers. It should have the same size as self + * @return [CvMat] Output image + * @opencv_func cvWatershed + */ +VALUE +rb_watershed(VALUE self, VALUE markers) +{ + try { + cvWatershed(CVARR(self), CVARR_WITH_CHECK(markers)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return markers; +} + +/* + * call-seq: + * moments -> cvmoments + * + * Calculates moments. + */ +VALUE +rb_moments(int argc, VALUE *argv, VALUE self) +{ + VALUE is_binary; + rb_scan_args(argc, argv, "01", &is_binary); + CvArr *self_ptr = CVARR(self); + VALUE moments = Qnil; + try { + moments = cCvMoments::new_object(self_ptr, TRUE_OR_FALSE(is_binary, 0)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return moments; +} + +/* + * Finds lines in binary image using a Hough transform. + * + * @overload hough_lines(method, rho, theta, threshold, param1, param2) + * @param method [Integer] The Hough transform variant, one of the following: + * * CV_HOUGH_STANDARD - classical or standard Hough transform. + * * CV_HOUGH_PROBABILISTIC - probabilistic Hough transform (more efficient in case if picture contains a few long linear segments). + * * CV_HOUGH_MULTI_SCALE - multi-scale variant of the classical Hough transform. The lines are encoded the same way as CV_HOUGH_STANDARD. + * @param rho [Number] Distance resolution in pixel-related units. + * @param theta [Number] Angle resolution measured in radians. + * @param threshold [Number] Threshold parameter. A line is returned by the function if the corresponding + * accumulator value is greater than threshold. + * @param param1 [Number] The first method-dependent parameter: + * * For the classical Hough transform it is not used (0). + * * For the probabilistic Hough transform it is the minimum line length. + * * For the multi-scale Hough transform it is the divisor for the distance resolution. + * (The coarse distance resolution will be rho and the accurate resolution will be (rho / param1)). + * @param param2 [Number] The second method-dependent parameter: + * * For the classical Hough transform it is not used (0). + * * For the probabilistic Hough transform it is the maximum gap between line segments lying + * on the same line to treat them as a single line segment (i.e. to join them). + * * For the multi-scale Hough transform it is the divisor for the angle resolution. + * (The coarse angle resolution will be theta and the accurate resolution will be (theta / param2).) + * @return [CvSeq] Output lines. If method is CV_HOUGH_STANDARD or CV_HOUGH_MULTI_SCALE, + * the class of elements is CvLine, otherwise CvTwoPoints. + * @opencv_func cvHoughLines2 + */ +VALUE +rb_hough_lines(int argc, VALUE *argv, VALUE self) +{ + const int INVALID_TYPE = -1; + VALUE method, rho, theta, threshold, p1, p2; + rb_scan_args(argc, argv, "42", &method, &rho, &theta, &threshold, &p1, &p2); + int method_flag = CVMETHOD("HOUGH_TRANSFORM_METHOD", method, INVALID_TYPE); + if (method_flag == INVALID_TYPE) + rb_raise(rb_eArgError, "Invalid method: %d", method_flag); + VALUE storage = cCvMemStorage::new_object(); + CvSeq *seq = NULL; + try { + seq = cvHoughLines2(CVARR(copy(self)), CVMEMSTORAGE(storage), + method_flag, NUM2DBL(rho), NUM2DBL(theta), NUM2INT(threshold), + IF_DBL(p1, 0), IF_DBL(p2, 0)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + switch (method_flag) { + case CV_HOUGH_STANDARD: + case CV_HOUGH_MULTI_SCALE: + return cCvSeq::new_sequence(cCvSeq::rb_class(), seq, cCvLine::rb_class(), storage); + break; + case CV_HOUGH_PROBABILISTIC: + return cCvSeq::new_sequence(cCvSeq::rb_class(), seq, cCvTwoPoints::rb_class(), storage); + break; + default: + break; + } + + return Qnil; +} + +/* + * Finds circles in a grayscale image using the Hough transform. + * + * @overload hough_circles(method, dp, min_dist, param1, param2, min_radius = 0, max_radius = 0) + * @param method [Integer] Detection method to use. Currently, the only implemented method is CV_HOUGH_GRADIENT. + * @param dp [Number] Inverse ratio of the accumulator resolution to the image resolution. + * For example, if dp=1, the accumulator has the same resolution as the input image. + * If dp=2, the accumulator has half as big width and height. + * @param min_dist [Number] Minimum distance between the centers of the detected circles. + * If the parameter is too small, multiple neighbor circles may be falsely detected + * in addition to a true one. If it is too large, some circles may be missed. + * @param param1 [Number] First method-specific parameter. In case of CV_HOUGH_GRADIENT, + * it is the higher threshold of the two passed to the #canny detector (the lower one is twice smaller). + * @param param2 [Number] Second method-specific parameter. In case of CV_HOUGH_GRADIENT, + * it is the accumulator threshold for the circle centers at the detection stage. The smaller it is, + * the more false circles may be detected. Circles, corresponding to the larger accumulator values, + * will be returned first. + * @return [CvSeq] Output circles. + * @opencv_func cvHoughCircles + */ +VALUE +rb_hough_circles(int argc, VALUE *argv, VALUE self) +{ + const int INVALID_TYPE = -1; + VALUE method, dp, min_dist, param1, param2, min_radius, max_radius, storage; + rb_scan_args(argc, argv, "52", &method, &dp, &min_dist, ¶m1, ¶m2, + &min_radius, &max_radius); + storage = cCvMemStorage::new_object(); + int method_flag = CVMETHOD("HOUGH_TRANSFORM_METHOD", method, INVALID_TYPE); + if (method_flag == INVALID_TYPE) + rb_raise(rb_eArgError, "Invalid method: %d", method_flag); + CvSeq *seq = NULL; + try { + seq = cvHoughCircles(CVARR(self), CVMEMSTORAGE(storage), + method_flag, NUM2DBL(dp), NUM2DBL(min_dist), + NUM2DBL(param1), NUM2DBL(param2), + IF_INT(min_radius, 0), IF_INT(max_radius, 0)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return cCvSeq::new_sequence(cCvSeq::rb_class(), seq, cCvCircle32f::rb_class(), storage); +} + +/* + * call-seq: + * inpaint(inpaint_method, mask, radius) -> cvmat + * + * Inpaints the selected region in the image + * The radius of circlular neighborhood of each point inpainted that is considered by the algorithm. + */ +VALUE +rb_inpaint(VALUE self, VALUE inpaint_method, VALUE mask, VALUE radius) +{ + const int INVALID_TYPE = -1; + VALUE dest = Qnil; + int method = CVMETHOD("INPAINT_METHOD", inpaint_method, INVALID_TYPE); + if (method == INVALID_TYPE) + rb_raise(rb_eArgError, "Invalid method"); + try { + CvArr* self_ptr = CVARR(self); + dest = new_mat_kind_object(cvGetSize(self_ptr), self); + cvInpaint(self_ptr, MASK(mask), CVARR(dest), NUM2DBL(radius), method); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * call-seq: + * equalize_hist -> cvmat + * + * Equalize histgram of grayscale of image. + * + * equalizes histogram of the input image using the following algorithm: + * 1. calculate histogram H for src. + * 2. normalize histogram, so that the sum of histogram bins is 255. + * 3. compute integral of the histogram: + * H’(i) = sum0≤j≤iH(j) + * 4. transform the image using H’ as a look-up table: dst(x,y)=H’(src(x,y)) + * The algorithm normalizes brightness and increases contrast of the image. + * + * support single-channel 8bit image (grayscale) only. + */ +VALUE +rb_equalize_hist(VALUE self) +{ + VALUE dest = Qnil; + try { + CvArr* self_ptr = CVARR(self); + dest = new_mat_kind_object(cvGetSize(self_ptr), self); + cvEqualizeHist(self_ptr, CVARR(dest)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return dest; +} + +/* + * call-seq: + * apply_color_map(colormap) -> cvmat + * + * Applies a GNU Octave/MATLAB equivalent colormap on a given image. + * + * Parameters: + * colormap - The colormap to apply. + */ +VALUE +rb_apply_color_map(VALUE self, VALUE colormap) +{ + VALUE dst; + try { + cv::Mat dst_mat; + cv::Mat self_mat(CVMAT(self)); + + cv::applyColorMap(self_mat, dst_mat, NUM2INT(colormap)); + CvMat tmp = dst_mat; + dst = new_object(tmp.rows, tmp.cols, tmp.type); + cvCopy(&tmp, CVMAT(dst)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return dst; +} + +/* + * Compares template against overlapped image regions. + * + * @overload match_template(template, method = CV_TM_SQDIFF) + * @param template [CvMat] Searched template. It must be not greater than the source image and have the same data type. + * @param method [Integer] Parameter specifying the comparison method. + * * CV_TM_SQDIFF + * * CV_TM_SQDIFF_NORMED + * * CV_TM_CCORR + * * CV_TM_CCORR_NORMED + * * CV_TM_CCOEFF + * * CV_TM_CCOEFF_NORMED + * @opencv_func cvMatchTemplate + * + * After the match_template finishes comparison, the best matches can be found as global + * minimums (CV_TM_SQDIFF) or maximums(CV_TM_CCORR or CV_TM_CCOEFF) using CvMat#min_max_loc. + * In case of color image and template summation in both numerator and each sum in denominator + * is done over all the channels (and separate mean values are used for each channel). + */ +VALUE +rb_match_template(int argc, VALUE *argv, VALUE self) +{ + VALUE templ, method; + int method_flag; + if (rb_scan_args(argc, argv, "11", &templ, &method) == 1) + method_flag = CV_TM_SQDIFF; + else + method_flag = CVMETHOD("MATCH_TEMPLATE_METHOD", method); + + CvArr* self_ptr = CVARR(self); + CvArr* templ_ptr = CVARR_WITH_CHECK(templ); + VALUE result = Qnil; + try { + CvSize src_size = cvGetSize(self_ptr); + CvSize template_size = cvGetSize(templ_ptr); + result = cCvMat::new_object(src_size.height - template_size.height + 1, + src_size.width - template_size.width + 1, + CV_32FC1); + cvMatchTemplate(self_ptr, templ_ptr, CVARR(result), method_flag); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return result; +} + +/* + * call-seq: + * match_shapes(object, method) -> float + * + * Compares two shapes(self and object). object should be CvMat or CvContour. + * + * A - object1, B - object2: + * * method=CV_CONTOURS_MATCH_I1 + * I1(A,B)=sumi=1..7abs(1/mAi - 1/mBi) + * * method=CV_CONTOURS_MATCH_I2 + * I2(A,B)=sumi=1..7abs(mAi - mBi) + * * method=CV_CONTOURS_MATCH_I3 + * I3(A,B)=sumi=1..7abs(mAi - mBi)/abs(mAi) + */ +VALUE +rb_match_shapes(int argc, VALUE *argv, VALUE self) +{ + VALUE object, method, param; + rb_scan_args(argc, argv, "21", &object, &method, ¶m); + int method_flag = CVMETHOD("COMPARISON_METHOD", method); + if (!(rb_obj_is_kind_of(object, cCvMat::rb_class()) || rb_obj_is_kind_of(object, cCvContour::rb_class()))) + rb_raise(rb_eTypeError, "argument 1 (shape) should be %s or %s", + rb_class2name(cCvMat::rb_class()), rb_class2name(cCvContour::rb_class())); + double result = 0; + try { + result = cvMatchShapes(CVARR(self), CVARR(object), method_flag); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_float_new(result); +} + +/* + * call-seq: + * mean_shift(window, criteria) -> comp + * + * Implements CAMSHIFT object tracking algrorithm. + * First, it finds an object center using mean_shift and, after that, + * calculates the object size and orientation. + */ +VALUE +rb_mean_shift(VALUE self, VALUE window, VALUE criteria) +{ + VALUE comp = cCvConnectedComp::new_object(); + try { + cvMeanShift(CVARR(self), VALUE_TO_CVRECT(window), VALUE_TO_CVTERMCRITERIA(criteria), CVCONNECTEDCOMP(comp)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return comp; +} + +/* + * call-seq: + * cam_shift(window, criteria) -> [comp, box] + * + * Implements CAMSHIFT object tracking algrorithm. First, it finds an object center using cvMeanShift and, + * after that, calculates the object size and orientation. The function returns number of iterations made + * within cvMeanShift. + */ +VALUE +rb_cam_shift(VALUE self, VALUE window, VALUE criteria) +{ + VALUE comp = cCvConnectedComp::new_object(); + VALUE box = cCvBox2D::new_object(); + try { + cvCamShift(CVARR(self), VALUE_TO_CVRECT(window), VALUE_TO_CVTERMCRITERIA(criteria), + CVCONNECTEDCOMP(comp), CVBOX2D(box)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_ary_new3(2, comp, box); +} + +/* + * call-seq: + * snake_image(points, alpha, beta, gamma, window, criteria[, calc_gradient = true]) -> array(pointset) + * + * Updates snake in order to minimize its total energy that is a sum of internal energy + * that depends on contour shape (the smoother contour is, the smaller internal energy is) + * and external energy that depends on the energy field and reaches minimum at the local energy + * extremums that correspond to the image edges in case of image gradient. + + * The parameter criteria.epsilon is used to define the minimal number of points that must be moved + * during any iteration to keep the iteration process running. + * + * If at some iteration the number of moved points is less than criteria.epsilon or + * the function performed criteria.max_iter iterations, the function terminates. + * + * points + * Contour points (snake). + * alpha + * Weight[s] of continuity energy, single float or array of length floats, one per each contour point. + * beta + * Weight[s] of curvature energy, similar to alpha. + * gamma + * Weight[s] of image energy, similar to alpha. + * window + * Size of neighborhood of every point used to search the minimum, both win.width and win.height must be odd. + * criteria + * Termination criteria. + * calc_gradient + * Gradient flag. If not 0, the function calculates gradient magnitude for every image pixel and consideres + * it as the energy field, otherwise the input image itself is considered. + */ +VALUE +rb_snake_image(int argc, VALUE *argv, VALUE self) +{ + VALUE points, alpha, beta, gamma, window, criteria, calc_gradient; + rb_scan_args(argc, argv, "61", &points, &alpha, &beta, &gamma, &window, &criteria, &calc_gradient); + CvPoint *pointset = 0; + int length = CVPOINTS_FROM_POINT_SET(points, &pointset); + int coeff = (TYPE(alpha) == T_ARRAY && TYPE(beta) == T_ARRAY && TYPE(gamma) == T_ARRAY) ? CV_ARRAY : CV_VALUE; + float *a = 0, *b = 0, *c = 0; + IplImage stub; + int i; + if (coeff == CV_VALUE) { + float buff_a, buff_b, buff_c; + buff_a = (float)NUM2DBL(alpha); + buff_b = (float)NUM2DBL(beta); + buff_c = (float)NUM2DBL(gamma); + a = &buff_a; + b = &buff_b; + c = &buff_c; + } + else { // CV_ARRAY + if ((RARRAY_LEN(alpha) != length) || + (RARRAY_LEN(beta) != length) || + (RARRAY_LEN(gamma) != length)) + rb_raise(rb_eArgError, "alpha, beta, gamma should be same size of points"); + a = RB_ALLOC_N(float, length); + b = RB_ALLOC_N(float, length); + c = RB_ALLOC_N(float, length); + for (i = 0; i < length; ++i) { + a[i] = (float)NUM2DBL(RARRAY_PTR(alpha)[i]); + b[i] = (float)NUM2DBL(RARRAY_PTR(beta)[i]); + c[i] = (float)NUM2DBL(RARRAY_PTR(gamma)[i]); + } + } + CvSize win = VALUE_TO_CVSIZE(window); + CvTermCriteria tc = VALUE_TO_CVTERMCRITERIA(criteria); + try { + cvSnakeImage(cvGetImage(CVARR(self), &stub), pointset, length, + a, b, c, coeff, win, tc, IF_BOOL(calc_gradient, 1, 0, 1)); + } + catch (cv::Exception& e) { + if (pointset != NULL) + cvFree(&pointset); + raise_cverror(e); + } + VALUE result = rb_ary_new2(length); + for (i = 0; i < length; ++i) + rb_ary_push(result, cCvPoint::new_object(pointset[i])); + cvFree(&pointset); + + return result; +} + +/* + * call-seq: + * optical_flow_hs(prev[,velx = nil][,vely = nil][,options]) -> [cvmat, cvmat] + * + * Calculates optical flow for two images (previous -> self) using Horn & Schunck algorithm. + * Return horizontal component of the optical flow and vertical component of the optical flow. + * prev is previous image + * velx is previous velocity field of x-axis, and vely is previous velocity field of y-axis. + * + * options + * * :lambda -> should be Float (default is 0.0005) + * Lagrangian multiplier. + * * :criteria -> should be CvTermCriteria object (default is CvTermCriteria(1, 0.001)) + * Criteria of termination of velocity computing. + * note: option's default value is CvMat::OPTICAL_FLOW_HS_OPTION. + * + * sample code + * velx, vely = nil, nil + * while true + * current = capture.query + * velx, vely = current.optical_flow_hs(prev, velx, vely) if prev + * prev = current + * end + */ +VALUE +rb_optical_flow_hs(int argc, VALUE *argv, VALUE self) +{ + VALUE prev, velx, vely, options; + int use_previous = 0; + rb_scan_args(argc, argv, "13", &prev, &velx, &vely, &options); + options = OPTICAL_FLOW_HS_OPTION(options); + CvMat *velx_ptr, *vely_ptr; + CvArr* self_ptr = CVARR(self); + try { + if (NIL_P(velx) && NIL_P(vely)) { + CvSize size = cvGetSize(self_ptr); + int type = CV_MAKETYPE(CV_32F, 1); + velx = cCvMat::new_object(size, type); + vely = cCvMat::new_object(size, type); + velx_ptr = CVMAT(velx); + vely_ptr = CVMAT(vely); + } + else { + use_previous = 1; + velx_ptr = CVMAT_WITH_CHECK(velx); + vely_ptr = CVMAT_WITH_CHECK(vely); + } + cvCalcOpticalFlowHS(CVMAT_WITH_CHECK(prev), self_ptr, use_previous, velx_ptr, vely_ptr, + HS_LAMBDA(options), HS_CRITERIA(options)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_ary_new3(2, velx, vely); +} + +/* + * call-seq: + * optical_flow_lk(prev, win_size) -> [cvmat, cvmat] + * + * Calculates optical flow for two images (previous -> self) using Lucas & Kanade algorithm + * Return horizontal component of the optical flow and vertical component of the optical flow. + * + * win_size is size of the averaging window used for grouping pixels. + */ +VALUE +rb_optical_flow_lk(VALUE self, VALUE prev, VALUE win_size) +{ + VALUE velx = Qnil; + VALUE vely = Qnil; + try { + CvArr* self_ptr = CVARR(self); + CvSize size = cvGetSize(self_ptr); + int type = CV_MAKETYPE(CV_32F, 1); + velx = cCvMat::new_object(size, type); + vely = cCvMat::new_object(size, type); + cvCalcOpticalFlowLK(CVMAT_WITH_CHECK(prev), self_ptr, VALUE_TO_CVSIZE(win_size), + CVARR(velx), CVARR(vely)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_ary_new3(2, velx, vely); +} + +/* + * call-seq: + * optical_flow_bm(prev[,velx = nil][,vely = nil][,option]) -> [cvmat, cvmat] + * + * Calculates optical flow for two images (previous -> self) using block matching method. + * Return horizontal component of the optical flow and vertical component of the optical flow. + * prev is previous image. + * velx is previous velocity field of x-axis, and vely is previous velocity field of y-axis. + * + * options + * * :block_size -> should be CvSize (default is CvSize(4,4)) + * Size of basic blocks that are compared. + * * :shift_size -> should be CvSize (default is CvSize(1,1)) + * Block coordinate increments. + * * :max_range -> should be CvSize (default is CVSize(4,4)) + * Size of the scanned neighborhood in pixels around block. + * note: option's default value is CvMat::OPTICAL_FLOW_BM_OPTION. + * + * Velocity is computed for every block, but not for every pixel, + * so velocity image pixels correspond to input image blocks. + * input/output velocity field's size should be (self.width / block_size.width)x(self.height / block_size.height). + * e.g. image.size is 320x240 and block_size is 4x4, velocity field's size is 80x60. + * + */ +VALUE +rb_optical_flow_bm(int argc, VALUE *argv, VALUE self) +{ + VALUE prev, velx, vely, options; + rb_scan_args(argc, argv, "13", &prev, &velx, &vely, &options); + options = OPTICAL_FLOW_BM_OPTION(options); + CvArr* self_ptr = CVARR(self); + CvSize block_size = BM_BLOCK_SIZE(options); + CvSize shift_size = BM_SHIFT_SIZE(options); + CvSize max_range = BM_MAX_RANGE(options); + + int use_previous = 0; + try { + CvSize image_size = cvGetSize(self_ptr); + CvSize velocity_size = cvSize((image_size.width - block_size.width + shift_size.width) / shift_size.width, + (image_size.height - block_size.height + shift_size.height) / shift_size.height); + CvMat *velx_ptr, *vely_ptr; + if (NIL_P(velx) && NIL_P(vely)) { + int type = CV_MAKETYPE(CV_32F, 1); + velx = cCvMat::new_object(velocity_size, type); + vely = cCvMat::new_object(velocity_size, type); + velx_ptr = CVMAT(velx); + vely_ptr = CVMAT(vely); + } + else { + use_previous = 1; + velx_ptr = CVMAT_WITH_CHECK(velx); + vely_ptr = CVMAT_WITH_CHECK(vely); + } + cvCalcOpticalFlowBM(CVMAT_WITH_CHECK(prev), self_ptr, + block_size, shift_size, max_range, use_previous, + velx_ptr, vely_ptr); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_ary_new3(2, velx, vely); +} + +/* + * call-seq: + * CvMat.find_fundamental_mat(points1, points2[,options = {}]) -> fundamental_matrix(cvmat) or nil + * + * Calculates fundamental matrix from corresponding points. + * Size of the output fundamental matrix is 3x3 or 9x3 (7-point method may return up to 3 matrices) + * + * points1 and points2 should be 2xN, Nx2, 3xN or Nx3 1-channel, or 1xN or Nx1 multi-channel matrix. + * method is method for computing the fundamental matrix + * - CV_FM_7POINT for a 7-point algorithm. (N = 7) + * - CV_FM_8POINT for an 8-point algorithm. (N >= 8) + * - CV_FM_RANSAC for the RANSAC algorithm. (N >= 8) + * - CV_FM_LMEDS for the LMedS algorithm. (N >= 8) + * option should be Hash include these keys. + * :with_status (true or false) + * If set true, return fundamental_matrix and status. [fundamental_matrix, status] + * Otherwise return fundamental matrix only(default). + * :maximum_distance + * The parameter is used for RANSAC. It is the maximum distance from point to epipolar line in pixels, beyond which the point is considered an outlier and is not used for computing the final fundamental matrix. It can be set to something like 1-3, depending on the accuracy of the point localization, image resolution and the image noise. + * :desirable_level + * The optional output array of N elements, every element of which is set to 0 for outliers and to 1 for the other points. The array is computed only in RANSAC and LMedS methods. For other methods it is set to all 1's. + * + * note: option's default value is CvMat::FIND_FUNDAMENTAL_MAT_OPTION. + */ +VALUE +rb_find_fundamental_mat(int argc, VALUE *argv, VALUE klass) +{ + VALUE points1, points2, method, option, fundamental_matrix, status; + int num = 0; + rb_scan_args(argc, argv, "31", &points1, &points2, &method, &option); + option = FIND_FUNDAMENTAL_MAT_OPTION(option); + int fm_method = FIX2INT(method); + CvMat *points1_ptr = CVMAT_WITH_CHECK(points1); + if (fm_method == CV_FM_7POINT) + fundamental_matrix = cCvMat::new_object(9, 3, CV_MAT_DEPTH(points1_ptr->type)); + else + fundamental_matrix = cCvMat::new_object(3, 3, CV_MAT_DEPTH(points1_ptr->type)); + + if (FFM_WITH_STATUS(option)) { + int status_len = (points1_ptr->rows > points1_ptr->cols) ? points1_ptr->rows : points1_ptr->cols; + status = cCvMat::new_object(1, status_len, CV_8UC1); + try { + num = cvFindFundamentalMat(points1_ptr, CVMAT_WITH_CHECK(points2), CVMAT(fundamental_matrix), fm_method, + FFM_MAXIMUM_DISTANCE(option), FFM_DESIRABLE_LEVEL(option), CVMAT(status)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return num == 0 ? Qnil : rb_ary_new3(2, fundamental_matrix, status); + } + else { + try { + num = cvFindFundamentalMat(points1_ptr, CVMAT_WITH_CHECK(points2), CVMAT(fundamental_matrix), fm_method, + FFM_MAXIMUM_DISTANCE(option), FFM_DESIRABLE_LEVEL(option), NULL); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return num == 0 ? Qnil : fundamental_matrix; + } +} + + +/* + * call-seq: + * CvMat.compute_correspond_epilines(points, which_image, fundamental_matrix) -> correspondent_lines(cvmat) + * + * For points in one image of stereo pair computes the corresponding epilines in the other image. + * Finds equation of a line that contains the corresponding point (i.e. projection of the same 3D point) + * in the other image. Each line is encoded by a vector of 3 elements l=[a,b,c]T, so that: + * lT*[x, y, 1]T=0, + * or + * a*x + b*y + c = 0 + * From the fundamental matrix definition (see cvFindFundamentalMatrix discussion), line l2 for a point p1 + * in the first image (which_image=1) can be computed as: + * l2=F*p1 + * and the line l1 for a point p2 in the second image (which_image=1) can be computed as: + * l1=FT*p2 + * Line coefficients are defined up to a scale. They are normalized (a2+b2=1) are stored into correspondent_lines. + */ +VALUE +rb_compute_correspond_epilines(VALUE klass, VALUE points, VALUE which_image, VALUE fundamental_matrix) +{ + VALUE correspondent_lines; + CvMat* points_ptr = CVMAT_WITH_CHECK(points); + int n; + if (points_ptr->cols <= 3 && points_ptr->rows >= 7) + n = points_ptr->rows; + else if (points_ptr->rows <= 3 && points_ptr->cols >= 7) + n = points_ptr->cols; + else + rb_raise(rb_eArgError, "input points should 2xN, Nx2 or 3xN, Nx3 matrix(N >= 7)."); + + correspondent_lines = cCvMat::new_object(n, 3, CV_MAT_DEPTH(points_ptr->type)); + try { + cvComputeCorrespondEpilines(points_ptr, NUM2INT(which_image), CVMAT_WITH_CHECK(fundamental_matrix), + CVMAT(correspondent_lines)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return correspondent_lines; +} + +/* + * Extracts Speeded Up Robust Features from an image + * + * @overload extract_surf(params, mask = nil) -> [cvseq(cvsurfpoint), array(float)] + * @param params [CvSURFParams] Various algorithm parameters put to the structure CvSURFParams. + * @param mask [CvMat] The optional input 8-bit mask. The features are only found + * in the areas that contain more than 50% of non-zero mask pixels. + * @return [Array, Array>] Output vector of keypoints and descriptors. + * @opencv_func cvExtractSURF + */ +VALUE +rb_extract_surf(int argc, VALUE *argv, VALUE self) +{ + VALUE _params, _mask; + rb_scan_args(argc, argv, "11", &_params, &_mask); + + // Prepare arguments + CvSURFParams params = *CVSURFPARAMS_WITH_CHECK(_params); + CvMat* mask = MASK(_mask); + VALUE storage = cCvMemStorage::new_object(); + CvSeq* keypoints = NULL; + CvSeq* descriptors = NULL; + + // Compute SURF keypoints and descriptors + try { + cvExtractSURF(CVARR(self), mask, &keypoints, &descriptors, CVMEMSTORAGE(storage), + params, 0); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + VALUE _keypoints = cCvSeq::new_sequence(cCvSeq::rb_class(), keypoints, cCvSURFPoint::rb_class(), storage); + + // Create descriptor array + const int DIM_SIZE = (params.extended) ? 128 : 64; + const int NUM_KEYPOINTS = keypoints->total; + VALUE _descriptors = rb_ary_new2(NUM_KEYPOINTS); + for (int m = 0; m < NUM_KEYPOINTS; ++m) { + VALUE elem = rb_ary_new2(DIM_SIZE); + float *descriptor = (float*)cvGetSeqElem(descriptors, m); + for (int n = 0; n < DIM_SIZE; ++n) { + rb_ary_store(elem, n, rb_float_new(descriptor[n])); + } + rb_ary_store(_descriptors, m, elem); + } + + return rb_assoc_new(_keypoints, _descriptors); +} + + +/* + * call-seq: + * subspace_project(w, mean) -> cvmat + */ +VALUE +rb_subspace_project(VALUE self, VALUE w, VALUE mean) +{ + VALUE projection; + try { + cv::Mat w_mat(CVMAT_WITH_CHECK(w)); + cv::Mat mean_mat(CVMAT_WITH_CHECK(mean)); + cv::Mat self_mat(CVMAT(self)); + cv::Mat pmat = cv::subspaceProject(w_mat, mean_mat, self_mat); + projection = new_object(pmat.rows, pmat.cols, pmat.type()); + CvMat tmp = pmat; + cvCopy(&tmp, CVMAT(projection)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return projection; +} + +/* + * call-seq: + * subspace_reconstruct(w, mean) -> cvmat + */ +VALUE +rb_subspace_reconstruct(VALUE self, VALUE w, VALUE mean) +{ + VALUE result; + try { + cv::Mat w_mat(CVMAT_WITH_CHECK(w)); + cv::Mat mean_mat(CVMAT_WITH_CHECK(mean)); + cv::Mat self_mat(CVMAT(self)); + cv::Mat rmat = cv::subspaceReconstruct(w_mat, mean_mat, self_mat); + result = new_object(rmat.rows, rmat.cols, rmat.type()); + CvMat tmp = rmat; + cvCopy(&tmp, CVMAT(result)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return result; +} + +VALUE +new_object(int rows, int cols, int type) +{ + return OPENCV_OBJECT(rb_klass, rb_cvCreateMat(rows, cols, type)); +} + +VALUE +new_object(CvSize size, int type) +{ + return OPENCV_OBJECT(rb_klass, rb_cvCreateMat(size.height, size.width, type)); +} + +VALUE +new_mat_kind_object(CvSize size, VALUE ref_obj) +{ + VALUE return_type = CLASS_OF(ref_obj); + if (rb_obj_is_kind_of(ref_obj, cIplImage::rb_class())) { + IplImage* img = IPLIMAGE(ref_obj); + return OPENCV_OBJECT(return_type, rb_cvCreateImage(size, img->depth, img->nChannels)); + } + else if (rb_obj_is_kind_of(ref_obj, rb_klass)) // CvMat + return OPENCV_OBJECT(return_type, rb_cvCreateMat(size.height, size.width, cvGetElemType(CVMAT(ref_obj)))); + else + rb_raise(rb_eNotImpError, "Only CvMat or IplImage are supported"); + + return Qnil; +} + +VALUE +new_mat_kind_object(CvSize size, VALUE ref_obj, int cvmat_depth, int channel) +{ + VALUE return_type = CLASS_OF(ref_obj); + if (rb_obj_is_kind_of(ref_obj, cIplImage::rb_class())) { + return OPENCV_OBJECT(return_type, rb_cvCreateImage(size, CV2IPL_DEPTH(cvmat_depth), channel)); + } + else if (rb_obj_is_kind_of(ref_obj, rb_klass)) // CvMat + return OPENCV_OBJECT(return_type, rb_cvCreateMat(size.height, size.width, + CV_MAKETYPE(cvmat_depth, channel))); + else + rb_raise(rb_eNotImpError, "Only CvMat or IplImage are supported"); + + return Qnil; +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + VALUE opencv = rb_module_opencv(); + + rb_klass = rb_define_class_under(opencv, "CvMat", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + + VALUE drawing_option = rb_hash_new(); + rb_define_const(rb_klass, "DRAWING_OPTION", drawing_option); + rb_hash_aset(drawing_option, ID2SYM(rb_intern("color")), cCvScalar::new_object(cvScalarAll(0))); + rb_hash_aset(drawing_option, ID2SYM(rb_intern("thickness")), INT2FIX(1)); + rb_hash_aset(drawing_option, ID2SYM(rb_intern("line_type")), INT2FIX(8)); + rb_hash_aset(drawing_option, ID2SYM(rb_intern("shift")), INT2FIX(0)); + + VALUE good_features_to_track_option = rb_hash_new(); + rb_define_const(rb_klass, "GOOD_FEATURES_TO_TRACK_OPTION", good_features_to_track_option); + rb_hash_aset(good_features_to_track_option, ID2SYM(rb_intern("max")), INT2FIX(0xFF)); + rb_hash_aset(good_features_to_track_option, ID2SYM(rb_intern("mask")), Qnil); + rb_hash_aset(good_features_to_track_option, ID2SYM(rb_intern("block_size")), INT2FIX(3)); + rb_hash_aset(good_features_to_track_option, ID2SYM(rb_intern("use_harris")), Qfalse); + rb_hash_aset(good_features_to_track_option, ID2SYM(rb_intern("k")), rb_float_new(0.04)); + + VALUE flood_fill_option = rb_hash_new(); + rb_define_const(rb_klass, "FLOOD_FILL_OPTION", flood_fill_option); + rb_hash_aset(flood_fill_option, ID2SYM(rb_intern("connectivity")), INT2FIX(4)); + rb_hash_aset(flood_fill_option, ID2SYM(rb_intern("fixed_range")), Qfalse); + rb_hash_aset(flood_fill_option, ID2SYM(rb_intern("mask_only")), Qfalse); + + VALUE find_contours_option = rb_hash_new(); + rb_define_const(rb_klass, "FIND_CONTOURS_OPTION", find_contours_option); + rb_hash_aset(find_contours_option, ID2SYM(rb_intern("mode")), INT2FIX(CV_RETR_LIST)); + rb_hash_aset(find_contours_option, ID2SYM(rb_intern("method")), INT2FIX(CV_CHAIN_APPROX_SIMPLE)); + rb_hash_aset(find_contours_option, ID2SYM(rb_intern("offset")), cCvPoint::new_object(cvPoint(0,0))); + + VALUE optical_flow_hs_option = rb_hash_new(); + rb_define_const(rb_klass, "OPTICAL_FLOW_HS_OPTION", optical_flow_hs_option); + rb_hash_aset(optical_flow_hs_option, ID2SYM(rb_intern("lambda")), rb_float_new(0.0005)); + rb_hash_aset(optical_flow_hs_option, ID2SYM(rb_intern("criteria")), cCvTermCriteria::new_object(cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 1, 0.001))); + + VALUE optical_flow_bm_option = rb_hash_new(); + rb_define_const(rb_klass, "OPTICAL_FLOW_BM_OPTION", optical_flow_bm_option); + rb_hash_aset(optical_flow_bm_option, ID2SYM(rb_intern("block_size")), cCvSize::new_object(cvSize(4, 4))); + rb_hash_aset(optical_flow_bm_option, ID2SYM(rb_intern("shift_size")), cCvSize::new_object(cvSize(1, 1))); + rb_hash_aset(optical_flow_bm_option, ID2SYM(rb_intern("max_range")), cCvSize::new_object(cvSize(4, 4))); + + VALUE find_fundamental_matrix_option = rb_hash_new(); + rb_define_const(rb_klass, "FIND_FUNDAMENTAL_MAT_OPTION", find_fundamental_matrix_option); + rb_hash_aset(find_fundamental_matrix_option, ID2SYM(rb_intern("with_status")), Qfalse); + rb_hash_aset(find_fundamental_matrix_option, ID2SYM(rb_intern("maximum_distance")), rb_float_new(1.0)); + rb_hash_aset(find_fundamental_matrix_option, ID2SYM(rb_intern("desirable_level")), rb_float_new(0.99)); + + rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_singleton_method(rb_klass, "load", RUBY_METHOD_FUNC(rb_load_imageM), -1); + // Ruby/OpenCV original functions + rb_define_method(rb_klass, "method_missing", RUBY_METHOD_FUNC(rb_method_missing), -1); + rb_define_method(rb_klass, "to_s", RUBY_METHOD_FUNC(rb_to_s), 0); + rb_define_method(rb_klass, "inside?", RUBY_METHOD_FUNC(rb_inside_q), 1); + rb_define_method(rb_klass, "to_IplConvKernel", RUBY_METHOD_FUNC(rb_to_IplConvKernel), 1); + rb_define_method(rb_klass, "create_mask", RUBY_METHOD_FUNC(rb_create_mask), 0); + + rb_define_method(rb_klass, "width", RUBY_METHOD_FUNC(rb_width), 0); + rb_define_alias(rb_klass, "columns", "width"); + rb_define_alias(rb_klass, "cols", "width"); + rb_define_method(rb_klass, "height", RUBY_METHOD_FUNC(rb_height), 0); + rb_define_alias(rb_klass, "rows", "height"); + rb_define_method(rb_klass, "depth", RUBY_METHOD_FUNC(rb_depth), 0); + rb_define_method(rb_klass, "channel", RUBY_METHOD_FUNC(rb_channel), 0); + rb_define_method(rb_klass, "data", RUBY_METHOD_FUNC(rb_data), 0); + + rb_define_method(rb_klass, "clone", RUBY_METHOD_FUNC(rb_clone), 0); + rb_define_method(rb_klass, "copy", RUBY_METHOD_FUNC(rb_copy), -1); + rb_define_method(rb_klass, "to_8u", RUBY_METHOD_FUNC(rb_to_8u), 0); + rb_define_method(rb_klass, "to_8s", RUBY_METHOD_FUNC(rb_to_8s), 0); + rb_define_method(rb_klass, "to_16u", RUBY_METHOD_FUNC(rb_to_16u), 0); + rb_define_method(rb_klass, "to_16s", RUBY_METHOD_FUNC(rb_to_16s), 0); + rb_define_method(rb_klass, "to_32s", RUBY_METHOD_FUNC(rb_to_32s), 0); + rb_define_method(rb_klass, "to_32f", RUBY_METHOD_FUNC(rb_to_32f), 0); + rb_define_method(rb_klass, "to_64f", RUBY_METHOD_FUNC(rb_to_64f), 0); + rb_define_method(rb_klass, "vector?", RUBY_METHOD_FUNC(rb_vector_q), 0); + rb_define_method(rb_klass, "square?", RUBY_METHOD_FUNC(rb_square_q), 0); + + rb_define_method(rb_klass, "to_CvMat", RUBY_METHOD_FUNC(rb_to_CvMat), 0); + rb_define_method(rb_klass, "sub_rect", RUBY_METHOD_FUNC(rb_sub_rect), -2); + rb_define_alias(rb_klass, "subrect", "sub_rect"); + rb_define_method(rb_klass, "get_rows", RUBY_METHOD_FUNC(rb_get_rows), -1); + rb_define_method(rb_klass, "get_cols", RUBY_METHOD_FUNC(rb_get_cols), 1); + rb_define_method(rb_klass, "each_row", RUBY_METHOD_FUNC(rb_each_row), 0); + rb_define_method(rb_klass, "each_col", RUBY_METHOD_FUNC(rb_each_col), 0); + rb_define_alias(rb_klass, "each_column", "each_col"); + rb_define_method(rb_klass, "diag", RUBY_METHOD_FUNC(rb_diag), -1); + rb_define_alias(rb_klass, "diagonal", "diag"); + rb_define_method(rb_klass, "size", RUBY_METHOD_FUNC(rb_size), 0); + rb_define_method(rb_klass, "dims", RUBY_METHOD_FUNC(rb_dims), 0); + rb_define_method(rb_klass, "dim_size", RUBY_METHOD_FUNC(rb_dim_size), 1); + rb_define_method(rb_klass, "[]", RUBY_METHOD_FUNC(rb_aref), -2); + rb_define_alias(rb_klass, "at", "[]"); + rb_define_method(rb_klass, "[]=", RUBY_METHOD_FUNC(rb_aset), -2); + rb_define_method(rb_klass, "set_data", RUBY_METHOD_FUNC(rb_set_data), 1); + rb_define_method(rb_klass, "set", RUBY_METHOD_FUNC(rb_set), -1); + rb_define_alias(rb_klass, "fill", "set"); + rb_define_method(rb_klass, "set!", RUBY_METHOD_FUNC(rb_set_bang), -1); + rb_define_alias(rb_klass, "fill!", "set!"); + rb_define_method(rb_klass, "set_zero", RUBY_METHOD_FUNC(rb_set_zero), 0); + rb_define_alias(rb_klass, "clear", "set_zero"); + rb_define_alias(rb_klass, "zero", "set_zero"); + rb_define_method(rb_klass, "set_zero!", RUBY_METHOD_FUNC(rb_set_zero_bang), 0); + rb_define_alias(rb_klass, "clear!", "set_zero!"); + rb_define_alias(rb_klass, "zero!", "set_zero!"); + rb_define_method(rb_klass, "identity", RUBY_METHOD_FUNC(rb_set_identity), -1); + rb_define_method(rb_klass, "identity!", RUBY_METHOD_FUNC(rb_set_identity_bang), -1); + rb_define_method(rb_klass, "range", RUBY_METHOD_FUNC(rb_range), 2); + rb_define_method(rb_klass, "range!", RUBY_METHOD_FUNC(rb_range_bang), 2); + + rb_define_method(rb_klass, "reshape", RUBY_METHOD_FUNC(rb_reshape), -1); + rb_define_method(rb_klass, "repeat", RUBY_METHOD_FUNC(rb_repeat), 1); + rb_define_method(rb_klass, "flip", RUBY_METHOD_FUNC(rb_flip), -1); + rb_define_method(rb_klass, "flip!", RUBY_METHOD_FUNC(rb_flip_bang), -1); + rb_define_method(rb_klass, "split", RUBY_METHOD_FUNC(rb_split), 0); + rb_define_singleton_method(rb_klass, "merge", RUBY_METHOD_FUNC(rb_merge), -2); + rb_define_method(rb_klass, "rand_shuffle", RUBY_METHOD_FUNC(rb_rand_shuffle), -1); + rb_define_method(rb_klass, "rand_shuffle!", RUBY_METHOD_FUNC(rb_rand_shuffle_bang), -1); + rb_define_method(rb_klass, "lut", RUBY_METHOD_FUNC(rb_lut), 1); + rb_define_method(rb_klass, "convert_scale", RUBY_METHOD_FUNC(rb_convert_scale), 1); + rb_define_method(rb_klass, "convert_scale_abs", RUBY_METHOD_FUNC(rb_convert_scale_abs), 1); + rb_define_method(rb_klass, "add", RUBY_METHOD_FUNC(rb_add), -1); + rb_define_alias(rb_klass, "+", "add"); + rb_define_method(rb_klass, "sub", RUBY_METHOD_FUNC(rb_sub), -1); + rb_define_alias(rb_klass, "-", "sub"); + rb_define_method(rb_klass, "mul", RUBY_METHOD_FUNC(rb_mul), -1); + rb_define_method(rb_klass, "mat_mul", RUBY_METHOD_FUNC(rb_mat_mul), -1); + rb_define_alias(rb_klass, "*", "mat_mul"); + rb_define_method(rb_klass, "div", RUBY_METHOD_FUNC(rb_div), -1); + rb_define_alias(rb_klass, "/", "div"); + rb_define_singleton_method(rb_klass, "add_weighted", RUBY_METHOD_FUNC(rb_add_weighted), 5); + rb_define_method(rb_klass, "and", RUBY_METHOD_FUNC(rb_and), -1); + rb_define_alias(rb_klass, "&", "and"); + rb_define_method(rb_klass, "or", RUBY_METHOD_FUNC(rb_or), -1); + rb_define_alias(rb_klass, "|", "or"); + rb_define_method(rb_klass, "xor", RUBY_METHOD_FUNC(rb_xor), -1); + rb_define_alias(rb_klass, "^", "xor"); + rb_define_method(rb_klass, "not", RUBY_METHOD_FUNC(rb_not), 0); + rb_define_method(rb_klass, "not!", RUBY_METHOD_FUNC(rb_not_bang), 0); + rb_define_method(rb_klass, "eq", RUBY_METHOD_FUNC(rb_eq), 1); + rb_define_method(rb_klass, "gt", RUBY_METHOD_FUNC(rb_gt), 1); + rb_define_method(rb_klass, "ge", RUBY_METHOD_FUNC(rb_ge), 1); + rb_define_method(rb_klass, "lt", RUBY_METHOD_FUNC(rb_lt), 1); + rb_define_method(rb_klass, "le", RUBY_METHOD_FUNC(rb_le), 1); + rb_define_method(rb_klass, "ne", RUBY_METHOD_FUNC(rb_ne), 1); + rb_define_method(rb_klass, "in_range", RUBY_METHOD_FUNC(rb_in_range), 2); + rb_define_method(rb_klass, "abs_diff", RUBY_METHOD_FUNC(rb_abs_diff), 1); + rb_define_method(rb_klass, "normalize", RUBY_METHOD_FUNC(rb_normalize), -1); + rb_define_method(rb_klass, "count_non_zero", RUBY_METHOD_FUNC(rb_count_non_zero), 0); + rb_define_method(rb_klass, "sum", RUBY_METHOD_FUNC(rb_sum), 0); + rb_define_method(rb_klass, "avg", RUBY_METHOD_FUNC(rb_avg), -1); + rb_define_method(rb_klass, "avg_sdv", RUBY_METHOD_FUNC(rb_avg_sdv), -1); + rb_define_method(rb_klass, "sdv", RUBY_METHOD_FUNC(rb_sdv), -1); + rb_define_method(rb_klass, "min_max_loc", RUBY_METHOD_FUNC(rb_min_max_loc), -1); + rb_define_singleton_method(rb_klass, "norm", RUBY_METHOD_FUNC(rb_norm), -1); + rb_define_method(rb_klass, "dot_product", RUBY_METHOD_FUNC(rb_dot_product), 1); + rb_define_method(rb_klass, "cross_product", RUBY_METHOD_FUNC(rb_cross_product), 1); + rb_define_method(rb_klass, "transform", RUBY_METHOD_FUNC(rb_transform), -1); + rb_define_method(rb_klass, "perspective_transform", RUBY_METHOD_FUNC(rb_perspective_transform), 1); + rb_define_method(rb_klass, "mul_transposed", RUBY_METHOD_FUNC(rb_mul_transposed), -1); + rb_define_method(rb_klass, "trace", RUBY_METHOD_FUNC(rb_trace), 0); + rb_define_method(rb_klass, "transpose", RUBY_METHOD_FUNC(rb_transpose), 0); + rb_define_alias(rb_klass, "t", "transpose"); + rb_define_method(rb_klass, "det", RUBY_METHOD_FUNC(rb_det), 0); + rb_define_alias(rb_klass, "determinant", "det"); + rb_define_method(rb_klass, "invert", RUBY_METHOD_FUNC(rb_invert), -1); + rb_define_singleton_method(rb_klass, "solve", RUBY_METHOD_FUNC(rb_solve), -1); + rb_define_method(rb_klass, "svd", RUBY_METHOD_FUNC(rb_svd), -1); + rb_define_method(rb_klass, "eigenvv", RUBY_METHOD_FUNC(rb_eigenvv), -1); + + /* drawing function */ + rb_define_method(rb_klass, "line", RUBY_METHOD_FUNC(rb_line), -1); + rb_define_method(rb_klass, "line!", RUBY_METHOD_FUNC(rb_line_bang), -1); + rb_define_method(rb_klass, "rectangle", RUBY_METHOD_FUNC(rb_rectangle), -1); + rb_define_method(rb_klass, "rectangle!", RUBY_METHOD_FUNC(rb_rectangle_bang), -1); + rb_define_method(rb_klass, "circle", RUBY_METHOD_FUNC(rb_circle), -1); + rb_define_method(rb_klass, "circle!", RUBY_METHOD_FUNC(rb_circle_bang), -1); + rb_define_method(rb_klass, "ellipse", RUBY_METHOD_FUNC(rb_ellipse), -1); + rb_define_method(rb_klass, "ellipse!", RUBY_METHOD_FUNC(rb_ellipse_bang), -1); + rb_define_method(rb_klass, "ellipse_box", RUBY_METHOD_FUNC(rb_ellipse_box), -1); + rb_define_method(rb_klass, "ellipse_box!", RUBY_METHOD_FUNC(rb_ellipse_box_bang), -1); + rb_define_method(rb_klass, "fill_poly", RUBY_METHOD_FUNC(rb_fill_poly), -1); + rb_define_method(rb_klass, "fill_poly!", RUBY_METHOD_FUNC(rb_fill_poly_bang), -1); + rb_define_method(rb_klass, "fill_convex_poly", RUBY_METHOD_FUNC(rb_fill_convex_poly), -1); + rb_define_method(rb_klass, "fill_convex_poly!", RUBY_METHOD_FUNC(rb_fill_convex_poly_bang), -1); + rb_define_method(rb_klass, "poly_line", RUBY_METHOD_FUNC(rb_poly_line), -1); + rb_define_method(rb_klass, "poly_line!", RUBY_METHOD_FUNC(rb_poly_line_bang), -1); + rb_define_method(rb_klass, "put_text", RUBY_METHOD_FUNC(rb_put_text), -1); + rb_define_method(rb_klass, "put_text!", RUBY_METHOD_FUNC(rb_put_text_bang), -1); + + rb_define_method(rb_klass, "dft", RUBY_METHOD_FUNC(rb_dft), -1); + rb_define_method(rb_klass, "dct", RUBY_METHOD_FUNC(rb_dct), -1); + + rb_define_method(rb_klass, "sobel", RUBY_METHOD_FUNC(rb_sobel), -1); + rb_define_method(rb_klass, "laplace", RUBY_METHOD_FUNC(rb_laplace), -1); + rb_define_method(rb_klass, "canny", RUBY_METHOD_FUNC(rb_canny), -1); + rb_define_method(rb_klass, "pre_corner_detect", RUBY_METHOD_FUNC(rb_pre_corner_detect), -1); + rb_define_method(rb_klass, "corner_eigenvv", RUBY_METHOD_FUNC(rb_corner_eigenvv), -1); + rb_define_method(rb_klass, "corner_min_eigen_val", RUBY_METHOD_FUNC(rb_corner_min_eigen_val), -1); + rb_define_method(rb_klass, "corner_harris", RUBY_METHOD_FUNC(rb_corner_harris), -1); + rb_define_method(rb_klass, "find_chessboard_corners", RUBY_METHOD_FUNC(rb_find_chessboard_corners), -1); + rb_define_method(rb_klass, "find_corner_sub_pix", RUBY_METHOD_FUNC(rb_find_corner_sub_pix), 4); + rb_define_method(rb_klass, "good_features_to_track", RUBY_METHOD_FUNC(rb_good_features_to_track), -1); + + rb_define_method(rb_klass, "rect_sub_pix", RUBY_METHOD_FUNC(rb_rect_sub_pix), -1); + rb_define_method(rb_klass, "quadrangle_sub_pix", RUBY_METHOD_FUNC(rb_quadrangle_sub_pix), -1); + rb_define_method(rb_klass, "resize", RUBY_METHOD_FUNC(rb_resize), -1); + rb_define_method(rb_klass, "warp_affine", RUBY_METHOD_FUNC(rb_warp_affine), -1); + rb_define_singleton_method(rb_klass, "rotation_matrix2D", RUBY_METHOD_FUNC(rb_rotation_matrix2D), 3); + rb_define_singleton_method(rb_klass, "get_perspective_transform", RUBY_METHOD_FUNC(rb_get_perspective_transform), 2); + rb_define_method(rb_klass, "warp_perspective", RUBY_METHOD_FUNC(rb_warp_perspective), -1); + rb_define_singleton_method(rb_klass, "find_homography", RUBY_METHOD_FUNC(rb_find_homography), -1); + rb_define_method(rb_klass, "remap", RUBY_METHOD_FUNC(rb_remap), -1); + rb_define_method(rb_klass, "log_polar", RUBY_METHOD_FUNC(rb_log_polar), -1); + + rb_define_method(rb_klass, "erode", RUBY_METHOD_FUNC(rb_erode), -1); + rb_define_method(rb_klass, "erode!", RUBY_METHOD_FUNC(rb_erode_bang), -1); + rb_define_method(rb_klass, "dilate", RUBY_METHOD_FUNC(rb_dilate), -1); + rb_define_method(rb_klass, "dilate!", RUBY_METHOD_FUNC(rb_dilate_bang), -1); + rb_define_method(rb_klass, "morphology", RUBY_METHOD_FUNC(rb_morphology), -1); + + rb_define_method(rb_klass, "smooth", RUBY_METHOD_FUNC(rb_smooth), -1); + rb_define_method(rb_klass, "copy_make_border", RUBY_METHOD_FUNC(rb_copy_make_border), -1); + rb_define_method(rb_klass, "filter2d", RUBY_METHOD_FUNC(rb_filter2d), -1); + rb_define_method(rb_klass, "integral", RUBY_METHOD_FUNC(rb_integral), -1); + rb_define_method(rb_klass, "threshold", RUBY_METHOD_FUNC(rb_threshold), -1); + rb_define_method(rb_klass, "adaptive_threshold", RUBY_METHOD_FUNC(rb_adaptive_threshold), -1); + + rb_define_method(rb_klass, "pyr_down", RUBY_METHOD_FUNC(rb_pyr_down), -1); + rb_define_method(rb_klass, "pyr_up", RUBY_METHOD_FUNC(rb_pyr_up), -1); + + rb_define_method(rb_klass, "flood_fill", RUBY_METHOD_FUNC(rb_flood_fill), -1); + rb_define_method(rb_klass, "flood_fill!", RUBY_METHOD_FUNC(rb_flood_fill_bang), -1); + rb_define_method(rb_klass, "find_contours", RUBY_METHOD_FUNC(rb_find_contours), -1); + rb_define_method(rb_klass, "find_contours!", RUBY_METHOD_FUNC(rb_find_contours_bang), -1); + rb_define_method(rb_klass, "draw_contours", RUBY_METHOD_FUNC(rb_draw_contours), -1); + rb_define_method(rb_klass, "draw_contours!", RUBY_METHOD_FUNC(rb_draw_contours_bang), -1); + rb_define_method(rb_klass, "draw_chessboard_corners", RUBY_METHOD_FUNC(rb_draw_chessboard_corners), 3); + rb_define_method(rb_klass, "draw_chessboard_corners!", RUBY_METHOD_FUNC(rb_draw_chessboard_corners_bang), 3); + rb_define_method(rb_klass, "pyr_mean_shift_filtering", RUBY_METHOD_FUNC(rb_pyr_mean_shift_filtering), -1); + rb_define_method(rb_klass, "watershed", RUBY_METHOD_FUNC(rb_watershed), 1); + + rb_define_method(rb_klass, "moments", RUBY_METHOD_FUNC(rb_moments), -1); + + rb_define_method(rb_klass, "hough_lines", RUBY_METHOD_FUNC(rb_hough_lines), -1); + rb_define_method(rb_klass, "hough_circles", RUBY_METHOD_FUNC(rb_hough_circles), -1); + + rb_define_method(rb_klass, "inpaint", RUBY_METHOD_FUNC(rb_inpaint), 3); + + rb_define_method(rb_klass, "equalize_hist", RUBY_METHOD_FUNC(rb_equalize_hist), 0); + rb_define_method(rb_klass, "apply_color_map", RUBY_METHOD_FUNC(rb_apply_color_map), 1); + rb_define_method(rb_klass, "match_template", RUBY_METHOD_FUNC(rb_match_template), -1); + rb_define_method(rb_klass, "match_shapes", RUBY_METHOD_FUNC(rb_match_shapes), -1); + + rb_define_method(rb_klass, "mean_shift", RUBY_METHOD_FUNC(rb_mean_shift), 2); + rb_define_method(rb_klass, "cam_shift", RUBY_METHOD_FUNC(rb_cam_shift), 2); + rb_define_method(rb_klass, "snake_image", RUBY_METHOD_FUNC(rb_snake_image), -1); + + rb_define_method(rb_klass, "optical_flow_hs", RUBY_METHOD_FUNC(rb_optical_flow_hs), -1); + rb_define_method(rb_klass, "optical_flow_lk", RUBY_METHOD_FUNC(rb_optical_flow_lk), 2); + rb_define_method(rb_klass, "optical_flow_bm", RUBY_METHOD_FUNC(rb_optical_flow_bm), -1); + + rb_define_singleton_method(rb_klass, "find_fundamental_mat", + RUBY_METHOD_FUNC(rb_find_fundamental_mat), -1); + rb_define_singleton_method(rb_klass, "compute_correspond_epilines", + RUBY_METHOD_FUNC(rb_compute_correspond_epilines), 3); + + rb_define_method(rb_klass, "extract_surf", RUBY_METHOD_FUNC(rb_extract_surf), -1); + + rb_define_method(rb_klass, "subspace_project", RUBY_METHOD_FUNC(rb_subspace_project), 2); + rb_define_method(rb_klass, "subspace_reconstruct", RUBY_METHOD_FUNC(rb_subspace_reconstruct), 2); + + rb_define_method(rb_klass, "save_image", RUBY_METHOD_FUNC(rb_save_image), -1); + rb_define_alias(rb_klass, "save", "save_image"); + + rb_define_method(rb_klass, "encode_image", RUBY_METHOD_FUNC(rb_encode_imageM), -1); + rb_define_alias(rb_klass, "encode", "encode_image"); + rb_define_singleton_method(rb_klass, "decode_image", RUBY_METHOD_FUNC(rb_decode_imageM), -1); + rb_define_alias(rb_singleton_class(rb_klass), "decode", "decode_image"); +} + +__NAMESPACE_END_OPENCV +__NAMESPACE_END_CVMAT + diff --git a/ext/cvmat.h b/ext/opencv/cvmat.h similarity index 66% rename from ext/cvmat.h rename to ext/opencv/cvmat.h index 45fa680b..168c2808 100644 --- a/ext/cvmat.h +++ b/ext/opencv/cvmat.h @@ -12,7 +12,8 @@ #include "opencv.h" -#define __NAMESPACE_BEGIN_CVMAT namespace cCvMat{ + +#define __NAMESPACE_BEGIN_CVMAT namespace cCvMat { #define __NAMESPACE_END_CVMAT } __NAMESPACE_BEGIN_OPENCV @@ -20,15 +21,16 @@ __NAMESPACE_BEGIN_CVMAT VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_allocate(VALUE klass); VALUE rb_initialize(int argc, VALUE *argv, VALUE self); +VALUE rb_load_imageM(int argc, VALUE *argv, VALUE self); +VALUE rb_encode_imageM(int argc, VALUE *argv, VALUE self); +VALUE rb_decode_imageM(int argc, VALUE *argv, VALUE self); VALUE rb_method_missing(int argc, VALUE *argv, VALUE self); VALUE rb_to_s(VALUE self); -VALUE rb_has_parent_q(VALUE self); -VALUE rb_parent(VALUE self); VALUE rb_inside_q(VALUE self, VALUE object); VALUE rb_to_IplConvKernel(VALUE self, VALUE anchor); VALUE rb_create_mask(VALUE self); @@ -56,10 +58,8 @@ VALUE rb_square_q(VALUE self); VALUE rb_to_CvMat(VALUE self); VALUE rb_to_IplImage(VALUE self); VALUE rb_sub_rect(VALUE self, VALUE args); -VALUE rb_slice_width(VALUE self, VALUE num); -VALUE rb_slice_height(VALUE self, VALUE num); -VALUE rb_row(VALUE self, VALUE args); -VALUE rb_col(VALUE self, VALUE args); +VALUE rb_get_rows(int argc, VALUE* argv, VALUE self); +VALUE rb_get_cols(VALUE self, VALUE col); VALUE rb_each_row(VALUE self); VALUE rb_each_col(VALUE self); VALUE rb_diag(int argc, VALUE *argv, VALUE self); @@ -68,22 +68,22 @@ VALUE rb_dims(VALUE self); VALUE rb_dim_size(VALUE self, VALUE index); VALUE rb_aref(VALUE self, VALUE args); VALUE rb_aset(VALUE self, VALUE args); -VALUE rb_fill(int argc, VALUE *argv, VALUE self); -VALUE rb_fill_bang(int argc, VALUE *argv, VALUE self); -VALUE rb_clear(VALUE self); -VALUE rb_clear_bang(VALUE self); +VALUE rb_set_data(VALUE self, VALUE data); +VALUE rb_set(int argc, VALUE *argv, VALUE self); +VALUE rb_set_bang(int argc, VALUE *argv, VALUE self); +VALUE rb_set_zero(VALUE self); +VALUE rb_set_zero_bang(VALUE self); VALUE rb_set_identity(int argc, VALUE *argv, VALUE self); VALUE rb_set_identity_bang(int argc, VALUE *argv, VALUE self); -VALUE rb_range(int argc, VALUE *argv, VALUE self); -VALUE rb_range_bang(int argc, VALUE *argv, VALUE self); +VALUE rb_range(VALUE self, VALUE start, VALUE end); +VALUE rb_range_bang(VALUE self, VALUE start, VALUE end); /* Transforms and Permutations */ -VALUE rb_reshape(VALUE self, VALUE hash); +VALUE rb_reshape(int argc, VALUE *argv, VALUE self); VALUE rb_repeat(VALUE self, VALUE object); VALUE rb_flip(int argc, VALUE *argv, VALUE self); VALUE rb_flip_bang(int argc, VALUE *argv, VALUE self); VALUE rb_split(VALUE self); VALUE rb_merge(VALUE klass, VALUE args); -VALUE rb_mix_channels(int argc, VALUE *argv, VALUE klass); VALUE rb_rand_shuffle(int argc, VALUE *argv, VALUE klass); VALUE rb_rand_shuffle_bang(int argc, VALUE *argv, VALUE klass); @@ -93,6 +93,7 @@ VALUE rb_convert_scale_abs(VALUE self, VALUE hash); VALUE rb_add(int argc, VALUE *argv, VALUE self); VALUE rb_sub(int argc, VALUE *argv, VALUE self); VALUE rb_mul(int argc, VALUE *argv, VALUE self); +VALUE rb_mat_mul(int argc, VALUE *argv, VALUE self); VALUE rb_div(int argc, VALUE *argv, VALUE self); VALUE rb_and(int argc, VALUE *argv, VALUE self); VALUE rb_or(int argc, VALUE *argv, VALUE self); @@ -108,6 +109,8 @@ VALUE rb_le(VALUE self, VALUE val); VALUE rb_ne(VALUE self, VALUE val); VALUE rb_in_range(VALUE self, VALUE min, VALUE max); VALUE rb_abs_diff(VALUE self, VALUE val); +VALUE rb_normalize(int argc, VALUE *argv, VALUE self); +VALUE rb_add_weighted(VALUE klass, VALUE src1, VALUE alpha, VALUE src2, VALUE beta, VALUE gamma); /* Statistics */ VALUE rb_count_non_zero(VALUE self); VALUE rb_sum(VALUE self); @@ -116,29 +119,23 @@ VALUE rb_avg_sdv(int argc, VALUE *argv, VALUE self); VALUE rb_sdv(int argc, VALUE *argv, VALUE self); VALUE rb_min_max_loc(int argc, VALUE *argv, VALUE self); -//VALUE rb_norm(); +VALUE rb_norm(int argc, VALUE *argv, VALUE self); VALUE rb_dot_product(VALUE self, VALUE mat); VALUE rb_cross_product(VALUE self, VALUE mat); // VALUE rb_gemm(); VALUE rb_transform(int argc, VALUE *argv, VALUE self); VALUE rb_perspective_transform(VALUE self, VALUE mat); -VALUE rb_mul_transposed(VALUE self, VALUE args); +VALUE rb_mul_transposed(int argc, VALUE *argv, VALUE self); VALUE rb_trace(VALUE self); VALUE rb_transpose(VALUE self); -VALUE rb_transpose_bang(VALUE self); VALUE rb_det(VALUE self); VALUE rb_invert(int argc, VALUE *argv, VALUE self); VALUE rb_solve(int argc, VALUE *argv, VALUE self); VALUE rb_svd(int argc, VALUE *argv, VALUE self); -VALUE rb_svbksb(int argc, VALUE *argv, VALUE self); VALUE rb_eigenvv(int argc, VALUE *argv, VALUE self); VALUE rb_eigenvv_bang(int argc, VALUE *argv, VALUE self); -VALUE rb_calc_covar_matrix(int argc, VALUE *argv, VALUE self); -VALUE rb_mahalonobis(int argc, VALUE *argv, VALUE self); VALUE rb_dft(int argc, VALUE *argv, VALUE self); -//VALUE rb_optimal_dft_size(VALUE self); -//VALUE rb_mul_spectrums(int argc, VALUE *argv, VALUE self); VALUE rb_dct(int argc, VALUE *argv, VALUE self); /* drawing function*/ @@ -158,9 +155,9 @@ VALUE rb_fill_convex_poly(int argc, VALUE *argv, VALUE self); VALUE rb_fill_convex_poly_bang(int argc, VALUE *argv, VALUE self); VALUE rb_poly_line(int argc, VALUE *argv, VALUE self); VALUE rb_poly_line_bang(int argc, VALUE *argv, VALUE self); - VALUE rb_put_text(int argc, VALUE *argv, VALUE self); VALUE rb_put_text_bang(int argc, VALUE *argv, VALUE self); + /* cv function */ VALUE rb_sobel(int argc, VALUE *argv, VALUE self); VALUE rb_laplace(int argc, VALUE *argv, VALUE self); @@ -169,44 +166,32 @@ VALUE rb_pre_corner_detect(int argc, VALUE *argv, VALUE self); VALUE rb_corner_eigenvv(int argc, VALUE *argv, VALUE self); VALUE rb_corner_min_eigen_val(int argc, VALUE *argv, VALUE self); VALUE rb_corner_harris(int argc, VALUE *argv, VALUE self); -VALUE rbi_find_corner_sub_pix(int argc, VALUE *argv, VALUE self); +VALUE rb_find_chessboard_corners(int argc, VALUE *argv, VALUE self); +VALUE rb_find_corner_sub_pix(VALUE self, VALUE corners, VALUE win_size, VALUE zero_zone, VALUE criteria); VALUE rb_good_features_to_track(int argc, VALUE *argv, VALUE self); -VALUE rb_sample_line(int argc, VALUE *argv, VALUE self); -VALUE rb_rect_sub_pix(VALUE self, VALUE center, VALUE size); -VALUE rb_quadrangle_sub_pix(VALUE self, VALUE map_matrix, VALUE size); +VALUE rb_rect_sub_pix(int argc, VALUE *argv, VALUE self); +VALUE rb_quadrangle_sub_pix(int argc, VALUE *argv, VALUE self); VALUE rb_resize(int argc, VALUE *argv, VALUE self); VALUE rb_warp_affine(int argc, VALUE *argv, VALUE self); -VALUE rb_rotation(VALUE self, VALUE center, VALUE angle, VALUE scale); +VALUE rb_rotation_matrix2D(VALUE self, VALUE center, VALUE angle, VALUE scale); +VALUE rb_get_perspective_transform(VALUE self, VALUE source, VALUE dest); VALUE rb_warp_perspective(int argc, VALUE *argv, VALUE self); -//VALUE rb_perspective_transform(); +VALUE rb_find_homography(int argc, VALUE *argv, VALUE self); VALUE rb_remap(int argc, VALUE *argv, VALUE self); -VALUE rb_log_polar(int argc, VALUE *argv); +VALUE rb_log_polar(int argc, VALUE *argv, VALUE self); VALUE rb_erode(int argc, VALUE *argv, VALUE self); VALUE rb_erode_bang(int argc, VALUE *argv, VALUE self); VALUE rb_dilate(int argc, VALUE *argv, VALUE self); VALUE rb_dilate_bang(int argc, VALUE *argv, VALUE self); -VALUE rb_morphology_open(int argc, VALUE *argv, VALUE self); -VALUE rb_morphology_close(int argc, VALUE *argv, VALUE self); -VALUE rb_morphology_gradient(int argc, VALUE *argv, VALUE self); -VALUE rb_morphology_tophat(int argc, VALUE *argv, VALUE self); -VALUE rb_morphology_blackhat(int argc, VALUE *argv, VALUE self); - -VALUE rb_smooth_blur_no_scale(int argc, VALUE *argv, VALUE self); -VALUE rb_smooth_blur(int argc, VALUE *argv, VALUE self); -VALUE rb_smooth_gaussian(int argc, VALUE *argv, VALUE self); -VALUE rb_smooth_median(int argc, VALUE *argv, VALUE self); -VALUE rb_smooth_bilateral(int argc, VALUE *argv, VALUE self); +VALUE rb_morphology(int argc, VALUE *argv, VALUE self); + +VALUE rb_smooth(int argc, VALUE *argv, VALUE self); +VALUE rb_copy_make_border(int argc, VALUE *argv, VALUE self); VALUE rb_filter2d(int argc, VALUE *argv, VALUE self); -VALUE rb_copy_make_border_constant(int argc, VALUE *argv, VALUE self); -VALUE rb_copy_make_border_replicate(int argc, VALUE *argv, VALUE self); VALUE rb_integral(int argc, VALUE *argv, VALUE self); -VALUE rb_threshold_binary(int argc, VALUE *argv, VALUE self); -VALUE rb_threshold_binary_inverse(int argc, VALUE *argv, VALUE self); -VALUE rb_threshold_trunc(int argc, VALUE *argv, VALUE self); -VALUE rb_threshold_to_zero(int argc, VALUE *argv, VALUE self); -VALUE rb_threshold_to_zero_inverse(int argc, VALUE *argv, VALUE self); +VALUE rb_threshold(int argc, VALUE *argv, VALUE self); VALUE rb_adaptive_threshold(int argc, VALUE *argv, VALUE self); VALUE rb_pyr_down(int argc, VALUE *argv, VALUE self); @@ -216,49 +201,56 @@ VALUE rb_flood_fill(int argc, VALUE *argv, VALUE self); VALUE rb_flood_fill_bang(int argc, VALUE *argv, VALUE self); VALUE rb_find_contours(int argc, VALUE *argv, VALUE self); VALUE rb_find_contours_bang(int argc, VALUE *argv, VALUE self); -VALUE rb_pyr_segmentation(int argc, VALUE *argv, VALUE self); +VALUE rb_draw_contours(int argc, VALUE *argv, VALUE self); +VALUE rb_draw_contours_bang(int argc, VALUE *argv, VALUE self); +VALUE rb_draw_chessboard_corners(VALUE self, VALUE pattern_size, VALUE corners, VALUE pattern_was_found); +VALUE rb_draw_chessboard_corners_bang(VALUE self, VALUE pattern_size, VALUE corners, VALUE pattern_was_found); VALUE rb_pyr_mean_shift_filtering(int argc, VALUE *argv, VALUE self); -VALUE rb_watershed(VALUE self); - +VALUE rb_watershed(VALUE self, VALUE markers); VALUE rb_moments(int argc, VALUE *argv, VALUE self); -VALUE rb_hough_lines_standard(int argc, VALUE *argv, VALUE self); -VALUE rb_hough_lines_probabilistic(int argc, VALUE *argv, VALUE self); -VALUE rb_hough_lines_multi_scale(int argc, VALUE *argv, VALUE self); -VALUE rb_hough_circles_gradient(int argc, VALUE *argv, VALUE self); +VALUE rb_hough_lines(int argc, VALUE *argv, VALUE self); +VALUE rb_hough_circles(int argc, VALUE *argv, VALUE self); VALUE rb_dist_transform(int argc, VALUE *argv, VALUE self); -VALUE rb_inpaint_ns(VALUE self, VALUE mask, VALUE radius); -VALUE rb_inpaint_telea(VALUE self, VALUE mask, VALUE radius); +VALUE rb_inpaint(VALUE self, VALUE inpaint_method, VALUE mask, VALUE radius); VALUE rb_equalize_hist(VALUE self); + +VALUE rb_apply_color_map(VALUE self, VALUE colormap); + /* Matching*/ VALUE rb_match_template(int argc, VALUE *argv, VALUE self); -VALUE rb_match_shapes_i1(int argc, VALUE *argv, VALUE self); -VALUE rb_match_shapes_i2(int argc, VALUE *argv, VALUE self); -VALUE rb_match_shapes_i3(int argc, VALUE *argv, VALUE self); -// VALUE rb_calc_emd(int argc, VALUE *argv, VALUE self); +VALUE rb_match_shapes(int argc, VALUE *argv, VALUE self); + /* Object Tracking */ VALUE rb_mean_shift(VALUE self, VALUE window, VALUE criteria); VALUE rb_cam_shift(VALUE self, VALUE window, VALUE criteria); VALUE rb_snake_image(int argc, VALUE *argv, VALUE self); /* Optical Flow */ VALUE rb_optical_flow_hs(int argc, VALUE *argv, VALUE self); -VALUE rb_optical_flow_lk(int argc, VALUE *argv, VALUE self); +VALUE rb_optical_flow_lk(VALUE self, VALUE prev, VALUE win_size); VALUE rb_optical_flow_bm(int argc, VALUE *argv, VALUE self); VALUE rb_optical_flow_pyr_lk(int argc, VALUE *argv, VALUE self); /* Epipolar Geometory */ -VALUE rb_find_fundamental_mat_7point(int argc, VALUE *argv, VALUE klass); -VALUE rb_find_fundamental_mat_8point(int argc, VALUE *argv, VALUE klass); -VALUE rb_find_fundamental_mat_ransac(int argc, VALUE *argv, VALUE klass); -VALUE rb_find_fundamental_mat_lmeds(int argc, VALUE *argv, VALUE klass); +VALUE rb_find_fundamental_mat(int argc, VALUE *argv, VALUE klass); VALUE rb_compute_correspond_epilines(VALUE klass, VALUE points, VALUE which_image, VALUE fundamental_matrix); - + +/* Feature detection and description */ +VALUE rb_extract_surf(int argc, VALUE *argv, VALUE self); + +VALUE rb_subspace_project(VALUE self, VALUE w, VALUE mean); +VALUE rb_subspace_reconstruct(VALUE self, VALUE w, VALUE mean); + // HighGUI function -VALUE rb_save_image(VALUE self, VALUE filename); +VALUE rb_save_image(int argc, VALUE *argv, VALUE self); VALUE new_object(int rows, int cols, int type); VALUE new_object(CvSize size, int type); +VALUE new_mat_kind_object(CvSize size, VALUE ref_obj); +VALUE new_mat_kind_object(CvSize size, VALUE ref_obj, int cvmat_depth, int channel); + +CvMat* prepare_decoding(int argc, VALUE *argv, int* iscolor, int* need_release); __NAMESPACE_END_CVMAT @@ -270,15 +262,27 @@ CVMAT(VALUE object) return cvGetMat(ptr, &stub); } +inline CvMat* +CVMAT_WITH_CHECK(VALUE object) +{ + if (!rb_obj_is_kind_of(object, cCvMat::rb_class())) + raise_typeerror(object, cCvMat::rb_class()); + return CVMAT(object); +} + inline CvMat* MASK(VALUE object) { - if(NIL_P(object)) + if (NIL_P(object)) return NULL; - else if(rb_obj_is_kind_of(object, cCvMat::rb_class()) && CV_MAT_CN(CVMAT(object)->type) == CV_8UC1) - return CVMAT(object); - else - rb_raise(rb_eTypeError, "object is not mask."); + else { + CvMat* obj_ptr = CVMAT_WITH_CHECK(object); + if (CV_MAT_DEPTH(obj_ptr->type) == CV_8UC1 && + CV_MAT_CN(obj_ptr->type) == 1) + return obj_ptr; + else + rb_raise(rb_eTypeError, "Mask should be 8bit 1-channel matrix."); + } } __NAMESPACE_END_OPENCV diff --git a/ext/cvmemstorage.cpp b/ext/opencv/cvmemstorage.cpp similarity index 61% rename from ext/cvmemstorage.cpp rename to ext/opencv/cvmemstorage.cpp index bc082912..79c0afa2 100644 --- a/ext/cvmemstorage.cpp +++ b/ext/opencv/cvmemstorage.cpp @@ -24,41 +24,50 @@ rb_class() return rb_klass; } -void -define_ruby_class() -{ - if(rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - rb_klass = rb_define_class_under(opencv, "CvMemStorage", rb_cObject); - //rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); -} - VALUE rb_allocate(VALUE klass) { - CvMemStorage *storage = cvCreateMemStorage(); - return Data_Wrap_Struct(klass, 0, free, storage); + CvMemStorage *storage = rb_cvCreateMemStorage(0); + return Data_Wrap_Struct(klass, 0, cvmemstorage_free, storage); } void -free(void *ptr) +cvmemstorage_free(void *ptr) { - cvReleaseMemStorage((CvMemStorage**)&ptr); + try { + cvReleaseMemStorage((CvMemStorage**)&ptr); + } + catch (cv::Exception& e) { + raise_cverror(e); + } } VALUE new_object(int blocksize) { - CvMemStorage *storage = cvCreateMemStorage(blocksize); - return Data_Wrap_Struct(rb_klass, 0, free, storage); + CvMemStorage *storage = rb_cvCreateMemStorage(blocksize); + return Data_Wrap_Struct(rb_klass, 0, cvmemstorage_free, storage); } +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + rb_klass = rb_define_class_under(opencv, "CvMemStorage", rb_cObject); +} __NAMESPACE_END_CVMEMSTORAGE __NAMESPACE_END_OPENCV + diff --git a/ext/cvmemstorage.h b/ext/opencv/cvmemstorage.h similarity index 70% rename from ext/cvmemstorage.h rename to ext/opencv/cvmemstorage.h index 1f800dac..9cb75337 100644 --- a/ext/cvmemstorage.h +++ b/ext/opencv/cvmemstorage.h @@ -12,17 +12,17 @@ #include "opencv.h" -#define __NAMESPACE_BEGIN_CVMEMSTORAGE namespace cCvMemStorage{ +#define __NAMESPACE_BEGIN_CVMEMSTORAGE namespace cCvMemStorage { #define __NAMESPACE_END_CVMEMSTORAGE } __NAMESPACE_BEGIN_OPENCV __NAMESPACE_BEGIN_CVMEMSTORAGE -void define_ruby_class(); +void init_ruby_class(); VALUE rb_class(); VALUE rb_allocate(VALUE klass); -void free(void *ptr); +void cvmemstorage_free(void *ptr); VALUE new_object(int blocksize = 0); @@ -39,13 +39,10 @@ CVMEMSTORAGE(VALUE object) inline VALUE CHECK_CVMEMSTORAGE(VALUE object) { - if(rb_obj_is_kind_of(object, cCvMemStorage::rb_class())) + if (rb_obj_is_kind_of(object, cCvMemStorage::rb_class())) { return object; - else{ - if(!NIL_P(object)) - rb_warn("invalid CvMemStorage object given. allocate new memory storage automatically."); - return cCvMemStorage::new_object(); } + return cCvMemStorage::new_object(); } __NAMESPACE_END_OPENCV diff --git a/ext/cvmoments.cpp b/ext/opencv/cvmoments.cpp similarity index 52% rename from ext/cvmoments.cpp rename to ext/opencv/cvmoments.cpp index ae47dcf3..8ac2c963 100644 --- a/ext/cvmoments.cpp +++ b/ext/opencv/cvmoments.cpp @@ -16,6 +16,12 @@ __NAMESPACE_BEGIN_OPENCV __NAMESPACE_BEGIN_CVMOMENTS +#define DEFINE_CVMOMENTS_ACCESSOR(elem) \ + rb_define_method(rb_klass, #elem, RUBY_METHOD_FUNC(rb_##elem), 0) + +#define CVMOMENTS_ACCESSOR(elem) \ + VALUE rb_##elem(VALUE self) { return DBL2NUM(CVMOMENTS(self)->elem); } + VALUE rb_klass; VALUE @@ -24,30 +30,6 @@ rb_class() return rb_klass; } -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - rb_klass = rb_define_class_under(opencv, "CvMoments", rb_cObject); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); - rb_define_method(rb_klass, "spatial", RUBY_METHOD_FUNC(rb_spatial), 2); - rb_define_method(rb_klass, "central", RUBY_METHOD_FUNC(rb_central), 2); - rb_define_method(rb_klass, "normalized_central", RUBY_METHOD_FUNC(rb_normalized_central), 2); - rb_define_method(rb_klass, "hu", RUBY_METHOD_FUNC(rb_hu), 0); - rb_define_method(rb_klass, "gravity_center", RUBY_METHOD_FUNC(rb_gravity_center), 0); - rb_define_alias(rb_klass, "center", "gravity_center"); - rb_define_method(rb_klass, "angle", RUBY_METHOD_FUNC(rb_angle), 0); -} - VALUE rb_allocate(VALUE klass) { @@ -56,7 +38,7 @@ rb_allocate(VALUE klass) } /* * call-seq: - * CvMoments.new(src[,is_binary = nil]) + * CvMoments.new(src[,is_binary = nil]) * * Calculates all moments up to third order of a polygon or rasterized shape. * src should be CvMat or CvPolygon. @@ -68,15 +50,43 @@ rb_initialize(int argc, VALUE *argv, VALUE self) { VALUE src, is_binary; rb_scan_args(argc, argv, "02", &src, &is_binary); - if (NIL_P(src)) - ; - else if (rb_obj_is_kind_of(src, cCvMat::rb_class()) || rb_obj_is_kind_of(src, cCvSeq::rb_class())) - cvMoments(CVARR(src), CVMOMENTS(self), TRUE_OR_FALSE(is_binary, 0)); - else - rb_raise(rb_eTypeError, "argument 1 (src) should be %s or %s.", rb_class2name(cCvMat::rb_class()), rb_class2name(cCvSeq::rb_class())); + if (!NIL_P(src)) { + if (rb_obj_is_kind_of(src, cCvMat::rb_class()) || rb_obj_is_kind_of(src, cCvSeq::rb_class())) { + try { + cvMoments(CVARR(src), CVMOMENTS(self), TRUE_OR_FALSE(is_binary, 0)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + } + else + rb_raise(rb_eTypeError, "argument 1 (src) should be %s or %s.", + rb_class2name(cCvMat::rb_class()), rb_class2name(cCvSeq::rb_class())); + } return self; } +CVMOMENTS_ACCESSOR(m00); +CVMOMENTS_ACCESSOR(m10); +CVMOMENTS_ACCESSOR(m01); +CVMOMENTS_ACCESSOR(m20); +CVMOMENTS_ACCESSOR(m11); +CVMOMENTS_ACCESSOR(m02); +CVMOMENTS_ACCESSOR(m30); +CVMOMENTS_ACCESSOR(m21); +CVMOMENTS_ACCESSOR(m12); +CVMOMENTS_ACCESSOR(m03); + +CVMOMENTS_ACCESSOR(mu20); +CVMOMENTS_ACCESSOR(mu11); +CVMOMENTS_ACCESSOR(mu02); +CVMOMENTS_ACCESSOR(mu30); +CVMOMENTS_ACCESSOR(mu21); +CVMOMENTS_ACCESSOR(mu12); +CVMOMENTS_ACCESSOR(mu03); + +CVMOMENTS_ACCESSOR(inv_sqrt_m00); + /* * call-seq: * spatial -> float @@ -90,7 +100,14 @@ rb_initialize(int argc, VALUE *argv, VALUE self) VALUE rb_spatial(VALUE self, VALUE x_order, VALUE y_order) { - return rb_float_new(cvGetSpatialMoment(CVMOMENTS(self), NUM2INT(x_order), NUM2INT(y_order))); + double result = 0; + try { + result = cvGetSpatialMoment(CVMOMENTS(self), NUM2INT(x_order), NUM2INT(y_order)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_float_new(result); } /* @@ -106,7 +123,14 @@ rb_spatial(VALUE self, VALUE x_order, VALUE y_order) VALUE rb_central(VALUE self, VALUE x_order, VALUE y_order) { - return rb_float_new(cvGetCentralMoment(CVMOMENTS(self), NUM2INT(x_order), NUM2INT(y_order))); + double result = 0; + try { + result = cvGetCentralMoment(CVMOMENTS(self), NUM2INT(x_order), NUM2INT(y_order)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_float_new(result); } /* @@ -120,12 +144,19 @@ rb_central(VALUE self, VALUE x_order, VALUE y_order) VALUE rb_normalized_central(VALUE self, VALUE x_order, VALUE y_order) { - return rb_float_new(cvGetNormalizedCentralMoment(CVMOMENTS(self), NUM2INT(x_order), NUM2INT(y_order))); + double result = 0; + try { + result = cvGetNormalizedCentralMoment(CVMOMENTS(self), NUM2INT(x_order), NUM2INT(y_order)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_float_new(result); } /* * call-seq: - * hu -> [hu1, hu2, ... ,hu7] + * hu -> cvhumoments * * Calculates seven Hu invariants. * @@ -142,16 +173,7 @@ rb_normalized_central(VALUE self, VALUE x_order, VALUE y_order) VALUE rb_hu(VALUE self) { - CvHuMoments hu_moments; - cvGetHuMoments(CVMOMENTS(self), &hu_moments); - return rb_ary_new3(7, - rb_float_new(hu_moments.hu1), - rb_float_new(hu_moments.hu2), - rb_float_new(hu_moments.hu3), - rb_float_new(hu_moments.hu4), - rb_float_new(hu_moments.hu5), - rb_float_new(hu_moments.hu6), - rb_float_new(hu_moments.hu7)); + return cCvHuMoments::new_object(CVMOMENTS(self)); } /* @@ -164,11 +186,18 @@ VALUE rb_gravity_center(VALUE self) { CvMoments *moments = CVMOMENTS(self); - double - m00 = cvGetSpatialMoment(moments, 0, 0), - m10 = cvGetSpatialMoment(moments, 1, 0), + CvPoint2D32f point; + double m00 = 0, m01 = 0, m10 = 0; + try { + m00 = cvGetSpatialMoment(moments, 0, 0); + m10 = cvGetSpatialMoment(moments, 1, 0); m01 = cvGetSpatialMoment(moments, 0, 1); - return cCvPoint2D32f::new_object(cvPoint2D32f(m10 / m00, m01 / m00)); + point = cvPoint2D32f(m10 / m00, m01 / m00); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return cCvPoint2D32f::new_object(point); } /* @@ -181,24 +210,84 @@ VALUE rb_angle(VALUE self) { CvMoments *moments = CVMOMENTS(self); - double - m11 = cvGetCentralMoment(moments, 1, 1), - m20 = cvGetCentralMoment(moments, 2, 0), - m02 = cvGetCentralMoment(moments, 0, 2), - mangle = 0.5 * atan(2 * m11 / (m20 - m02)); - if(!cvIsNaN(mangle) && !cvIsInf(mangle)) - return rb_float_new(mangle); - else + double m11 = 0, m20 = 0, m02 = 0; + try { + m11 = cvGetCentralMoment(moments, 1, 1); + m20 = cvGetCentralMoment(moments, 2, 0); + m02 = cvGetCentralMoment(moments, 0, 2); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + double mangle = 0.5 * atan(2 * m11 / (m20 - m02)); + if (cvIsNaN(mangle) || cvIsInf(mangle)) return Qnil; + else + return rb_float_new(mangle); } VALUE new_object(CvArr *arr, int is_binary = 0) { - VALUE object = rb_allocate(rb_class()); - cvMoments(arr, CVMOMENTS(object), TRUE_OR_FALSE(is_binary, 0)); + VALUE object = rb_allocate(rb_klass); + try { + cvMoments(arr, CVMOMENTS(object), is_binary); + } + catch (cv::Exception& e) { + raise_cverror(e); + } return object; } +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + + rb_klass = rb_define_class_under(opencv, "CvMoments", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "spatial", RUBY_METHOD_FUNC(rb_spatial), 2); + rb_define_method(rb_klass, "central", RUBY_METHOD_FUNC(rb_central), 2); + rb_define_method(rb_klass, "normalized_central", RUBY_METHOD_FUNC(rb_normalized_central), 2); + rb_define_method(rb_klass, "hu", RUBY_METHOD_FUNC(rb_hu), 0); + rb_define_method(rb_klass, "gravity_center", RUBY_METHOD_FUNC(rb_gravity_center), 0); + rb_define_method(rb_klass, "angle", RUBY_METHOD_FUNC(rb_angle), 0); + + DEFINE_CVMOMENTS_ACCESSOR(m00); + DEFINE_CVMOMENTS_ACCESSOR(m10); + DEFINE_CVMOMENTS_ACCESSOR(m01); + DEFINE_CVMOMENTS_ACCESSOR(m20); + DEFINE_CVMOMENTS_ACCESSOR(m11); + DEFINE_CVMOMENTS_ACCESSOR(m02); + DEFINE_CVMOMENTS_ACCESSOR(m30); + DEFINE_CVMOMENTS_ACCESSOR(m21); + DEFINE_CVMOMENTS_ACCESSOR(m12); + DEFINE_CVMOMENTS_ACCESSOR(m03); + + DEFINE_CVMOMENTS_ACCESSOR(mu20); + DEFINE_CVMOMENTS_ACCESSOR(mu11); + DEFINE_CVMOMENTS_ACCESSOR(mu02); + DEFINE_CVMOMENTS_ACCESSOR(mu30); + DEFINE_CVMOMENTS_ACCESSOR(mu21); + DEFINE_CVMOMENTS_ACCESSOR(mu12); + DEFINE_CVMOMENTS_ACCESSOR(mu03); + + DEFINE_CVMOMENTS_ACCESSOR(inv_sqrt_m00); +} + __NAMESPACE_END_CVMOMENTS __NAMESPACE_END_OPENCV + diff --git a/ext/cvmoments.h b/ext/opencv/cvmoments.h similarity index 57% rename from ext/cvmoments.h rename to ext/opencv/cvmoments.h index 9eda0025..700a248d 100644 --- a/ext/cvmoments.h +++ b/ext/opencv/cvmoments.h @@ -12,7 +12,7 @@ #include "opencv.h" -#define __NAMESPACE_BEGIN_CVMOMENTS namespace cCvMoments{ +#define __NAMESPACE_BEGIN_CVMOMENTS namespace cCvMoments { #define __NAMESPACE_END_CVMOMENTS } __NAMESPACE_BEGIN_OPENCV @@ -20,7 +20,7 @@ __NAMESPACE_BEGIN_CVMOMENTS VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_allocate(VALUE klass); VALUE rb_initialize(int argc, VALUE *argv, VALUE self); @@ -31,6 +31,25 @@ VALUE rb_hu(VALUE self); VALUE rb_gravity_center(VALUE self); VALUE rb_angle(VALUE self); +VALUE rb_m00(VALUE self); +VALUE rb_m10(VALUE self); +VALUE rb_m01(VALUE self); +VALUE rb_m20(VALUE self); +VALUE rb_m11(VALUE self); +VALUE rb_m02(VALUE self); +VALUE rb_m30(VALUE self); +VALUE rb_m21(VALUE self); +VALUE rb_m12(VALUE self); +VALUE rb_m03(VALUE self); +VALUE rb_mu20(VALUE self); +VALUE rb_mu11(VALUE self); +VALUE rb_mu02(VALUE self); +VALUE rb_mu30(VALUE self); +VALUE rb_mu21(VALUE self); +VALUE rb_mu12(VALUE self); +VALUE rb_mu03(VALUE self); +VALUE rb_inv_sqrt_m00(VALUE self); + VALUE new_object(CvArr *arr, int is_binary); __NAMESPACE_END_CVMOMENTS @@ -43,6 +62,14 @@ CVMOMENTS(VALUE object) return ptr; } +inline CvMoments* +CVMOMENTS_WITH_CHECK(VALUE object) +{ + if (!rb_obj_is_kind_of(object, cCvMoments::rb_class())) + raise_typeerror(object, cCvMoments::rb_class()); + return CVMOMENTS(object); +} + __NAMESPACE_END_OPENCV #endif // RUBY_OPENCV_CVMOMENTS_H diff --git a/ext/cvpoint.cpp b/ext/opencv/cvpoint.cpp similarity index 81% rename from ext/cvpoint.cpp rename to ext/opencv/cvpoint.cpp index 52bf680b..4252f6f3 100644 --- a/ext/cvpoint.cpp +++ b/ext/opencv/cvpoint.cpp @@ -12,10 +12,10 @@ * Document-class: OpenCV::CvPoint * * This class means one point on X axis Y axis. - * X and Y takes the value of the Fixnum. see also CvPoint2D32F + * X and Y takes the value of the Integer. see also CvPoint2D32F * * C structure is here, very simple. - * typdef struct CvPoint{ + * typdef struct CvPoint { * int x; * int y; * } @@ -31,31 +31,6 @@ rb_class() return rb_klass; } -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - rb_klass = rb_define_class_under(opencv, "CvPoint", rb_cObject); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_singleton_method(rb_klass, "compatible?", RUBY_METHOD_FUNC(rb_compatible_q), 1); - rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); - rb_define_method(rb_klass, "x", RUBY_METHOD_FUNC(rb_x), 0); - rb_define_method(rb_klass, "x=", RUBY_METHOD_FUNC(rb_set_x), 1); - rb_define_method(rb_klass, "y", RUBY_METHOD_FUNC(rb_y), 0); - rb_define_method(rb_klass, "y=", RUBY_METHOD_FUNC(rb_set_y), 1); - - rb_define_method(rb_klass, "to_s", RUBY_METHOD_FUNC(rb_to_s), 0); - rb_define_method(rb_klass, "to_ary", RUBY_METHOD_FUNC(rb_to_ary), 0); -} - /* * call-seq: * combatible?(obj) @@ -103,28 +78,25 @@ rb_allocate(VALUE klass) VALUE rb_initialize(int argc, VALUE *argv, VALUE self) { - VALUE obj, x, y; + CvPoint* self_ptr = CVPOINT(self); switch (argc) { case 0: break; - case 1: - obj = argv[0]; - if (rb_compatible_q(rb_klass, obj)) { - CVPOINT(self)->x = NUM2INT(rb_funcall(rb_funcall(obj, rb_intern("x"), 0), rb_intern("to_i"), 0)); - CVPOINT(self)->y = NUM2INT(rb_funcall(rb_funcall(obj, rb_intern("y"), 0), rb_intern("to_i"), 0)); - }else{ - rb_raise(rb_eArgError, "object is not compatible %s.", rb_class2name(rb_klass)); - } + case 1: { + CvPoint point = VALUE_TO_CVPOINT(argv[0]); + self_ptr->x = point.x; + self_ptr->y = point.y; break; + } case 2: - x = argv[0], y = argv[1]; - CVPOINT(self)->x = NUM2INT(x); - CVPOINT(self)->y = NUM2INT(y); + self_ptr->x = NUM2INT(argv[0]); + self_ptr->y = NUM2INT(argv[1]); break; default: rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc); + break; } - return Qnil; + return self; } /* @@ -133,7 +105,7 @@ rb_initialize(int argc, VALUE *argv, VALUE self) VALUE rb_x(VALUE self) { - return INT2FIX(CVPOINT(self)->x); + return INT2NUM(CVPOINT(self)->x); } /* @@ -161,7 +133,7 @@ rb_set_x(VALUE self, VALUE x) VALUE rb_y(VALUE self) { - return INT2FIX(CVPOINT(self)->y); + return INT2NUM(CVPOINT(self)->y); } /* @@ -205,7 +177,8 @@ rb_to_s(VALUE self) VALUE rb_to_ary(VALUE self) { - return rb_ary_new3(2, rb_x(self), rb_y(self)); + CvPoint* self_ptr = CVPOINT(self); + return rb_ary_new3(2, INT2NUM(self_ptr->x), INT2NUM(self_ptr->y)); } VALUE @@ -225,5 +198,37 @@ new_object(CvPoint point) return object; } +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + + rb_klass = rb_define_class_under(opencv, "CvPoint", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_singleton_method(rb_klass, "compatible?", RUBY_METHOD_FUNC(rb_compatible_q), 1); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "x", RUBY_METHOD_FUNC(rb_x), 0); + rb_define_method(rb_klass, "x=", RUBY_METHOD_FUNC(rb_set_x), 1); + rb_define_method(rb_klass, "y", RUBY_METHOD_FUNC(rb_y), 0); + rb_define_method(rb_klass, "y=", RUBY_METHOD_FUNC(rb_set_y), 1); + + rb_define_method(rb_klass, "to_s", RUBY_METHOD_FUNC(rb_to_s), 0); + rb_define_method(rb_klass, "to_ary", RUBY_METHOD_FUNC(rb_to_ary), 0); + rb_define_alias(rb_klass, "to_a", "to_ary"); +} + __NAMESPACE_END_CVPOINT __NAMESPACE_END_OPENCV + diff --git a/ext/cvpoint.h b/ext/opencv/cvpoint.h similarity index 75% rename from ext/cvpoint.h rename to ext/opencv/cvpoint.h index 488c6e4b..d72d43f4 100644 --- a/ext/cvpoint.h +++ b/ext/opencv/cvpoint.h @@ -12,7 +12,7 @@ #include "opencv.h" -#define __NAMESPACE_BEGIN_CVPOINT namespace cCvPoint{ +#define __NAMESPACE_BEGIN_CVPOINT namespace cCvPoint { #define __NAMESPACE_END_CVPOINT } __NAMESPACE_BEGIN_OPENCV @@ -20,7 +20,7 @@ __NAMESPACE_BEGIN_CVPOINT VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_compatible_q(VALUE klass, VALUE object); @@ -39,19 +39,24 @@ VALUE new_object(CvPoint point); __NAMESPACE_END_CVPOINT -inline CvPoint *CVPOINT(VALUE object){ +inline CvPoint* +CVPOINT(VALUE object){ CvPoint *ptr; Data_Get_Struct(object, CvPoint, ptr); return ptr; } -inline CvPoint VALUE_TO_CVPOINT(VALUE object){ - if(cCvPoint::rb_compatible_q(cCvPoint::rb_class(), object)){ +inline CvPoint +VALUE_TO_CVPOINT(VALUE object) +{ + if (cCvPoint::rb_compatible_q(cCvPoint::rb_class(), object)) { return cvPoint(NUM2INT(rb_funcall(object, rb_intern("x"), 0)), NUM2INT(rb_funcall(object, rb_intern("y"), 0))); - }else{ - rb_raise(rb_eTypeError, "require %s or compatible object.", rb_class2name(cCvPoint::rb_class())); } + else { + raise_compatible_typeerror(object, cCvPoint::rb_class()); + } + throw "Should never reach here"; } __NAMESPACE_END_OPENCV diff --git a/ext/cvpoint2d32f.cpp b/ext/opencv/cvpoint2d32f.cpp similarity index 82% rename from ext/cvpoint2d32f.cpp rename to ext/opencv/cvpoint2d32f.cpp index 05b5b0e8..836e6ad6 100644 --- a/ext/cvpoint2d32f.cpp +++ b/ext/opencv/cvpoint2d32f.cpp @@ -7,7 +7,7 @@ Copyright (C) 2005 Masakazu Yonekura ************************************************************/ -#include"cvpoint2d32f.h" +#include "cvpoint2d32f.h" /* * Document-class: OpenCV::CvPoint2D32f * @@ -15,7 +15,7 @@ * X and Y takes the value of the Float. see also CvPoint * * C structure is here, very simple. - * typdef struct CvPoint2D32f{ + * typdef struct CvPoint2D32f { * float x; * float y; * } @@ -31,31 +31,6 @@ rb_class() return rb_klass; } -void -define_ruby_class() -{ - if(rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - rb_klass = rb_define_class_under(opencv, "CvPoint2D32f", rb_cObject); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_singleton_method(rb_klass, "compatible?", RUBY_METHOD_FUNC(rb_compatible_q), 1); - rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); - rb_define_method(rb_klass, "x", RUBY_METHOD_FUNC(rb_x), 0); - rb_define_method(rb_klass, "x=", RUBY_METHOD_FUNC(rb_set_x), 1); - rb_define_method(rb_klass, "y", RUBY_METHOD_FUNC(rb_y), 0); - rb_define_method(rb_klass, "y=", RUBY_METHOD_FUNC(rb_set_y), 1); - - rb_define_method(rb_klass, "to_s", RUBY_METHOD_FUNC(rb_to_s), 0); - rb_define_method(rb_klass, "to_ary", RUBY_METHOD_FUNC(rb_to_ary), 0); -} - /* * call-seq: * combatible?(obj) @@ -103,28 +78,25 @@ rb_allocate(VALUE klass) VALUE rb_initialize(int argc, VALUE *argv, VALUE self) { - VALUE obj, x, y; + CvPoint2D32f *self_ptr = CVPOINT2D32F(self); switch (argc) { case 0: break; - case 1: - obj = argv[0]; - if(rb_compatible_q(rb_klass, obj)) { - CVPOINT2D32F(self)->x = NUM2DBL(rb_funcall(rb_funcall(obj, rb_intern("x"), 0), rb_intern("to_f"), 0)); - CVPOINT2D32F(self)->y = NUM2DBL(rb_funcall(rb_funcall(obj, rb_intern("y"), 0), rb_intern("to_f"), 0)); - }else{ - rb_raise(rb_eArgError, "object is not compatible %s.", rb_class2name(rb_klass)); - } + case 1: { + CvPoint2D32f point = VALUE_TO_CVPOINT2D32F(argv[0]); + self_ptr->x = point.x; + self_ptr->y = point.y; break; + } case 2: - x = argv[0], y = argv[1]; - CVPOINT2D32F(self)->x = NUM2DBL(x); - CVPOINT2D32F(self)->y = NUM2DBL(y); + self_ptr->x = NUM2DBL(argv[0]); + self_ptr->y = NUM2DBL(argv[1]); break; default: rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc); + break; } - return Qnil; + return self; } /* @@ -182,7 +154,7 @@ rb_to_s(VALUE self) { const int i = 4; VALUE str[i]; - str[0] = rb_str_new2("<%s:(%f,%f)>"); + str[0] = rb_str_new2("<%s:(%g,%g)>"); str[1] = rb_str_new2(rb_class2name(CLASS_OF(self))); str[2] = rb_x(self); str[3] = rb_y(self); @@ -209,5 +181,36 @@ new_object(CvPoint2D32f point) return object; } +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + + rb_klass = rb_define_class_under(opencv, "CvPoint2D32f", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_singleton_method(rb_klass, "compatible?", RUBY_METHOD_FUNC(rb_compatible_q), 1); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "x", RUBY_METHOD_FUNC(rb_x), 0); + rb_define_method(rb_klass, "x=", RUBY_METHOD_FUNC(rb_set_x), 1); + rb_define_method(rb_klass, "y", RUBY_METHOD_FUNC(rb_y), 0); + rb_define_method(rb_klass, "y=", RUBY_METHOD_FUNC(rb_set_y), 1); + + rb_define_method(rb_klass, "to_s", RUBY_METHOD_FUNC(rb_to_s), 0); + rb_define_method(rb_klass, "to_ary", RUBY_METHOD_FUNC(rb_to_ary), 0); + rb_define_alias(rb_klass, "to_a", "to_ary"); +} + __NAMESPACE_END_CVPOINT2D32F __NAMESPACE_END_OPENCV diff --git a/ext/cvpoint2d32f.h b/ext/opencv/cvpoint2d32f.h similarity index 79% rename from ext/cvpoint2d32f.h rename to ext/opencv/cvpoint2d32f.h index 2e7c60c1..7635c1fe 100644 --- a/ext/cvpoint2d32f.h +++ b/ext/opencv/cvpoint2d32f.h @@ -10,17 +10,17 @@ #ifndef RUBY_OPENCV_CVPOINT2D32F_H #define RUBY_OPENCV_CVPOINT2D32F_H -#define __NAMESPACE_BEGIN_CVPOINT2D32F namespace cCvPoint2D32f{ +#define __NAMESPACE_BEGIN_CVPOINT2D32F namespace cCvPoint2D32f { #define __NAMESPACE_END_CVPOINT2D32F } -#include"opencv.h" +#include "opencv.h" __NAMESPACE_BEGIN_OPENCV __NAMESPACE_BEGIN_CVPOINT2D32F VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_compatible_q(VALUE klass, VALUE object); @@ -49,12 +49,14 @@ CVPOINT2D32F(VALUE object) inline CvPoint2D32f VALUE_TO_CVPOINT2D32F(VALUE object) { - if(cCvPoint2D32f::rb_compatible_q(cCvPoint2D32f::rb_class(), object)){ + if (cCvPoint2D32f::rb_compatible_q(cCvPoint2D32f::rb_class(), object)) { return cvPoint2D32f(NUM2DBL(rb_funcall(object, rb_intern("x"), 0)), NUM2DBL(rb_funcall(object, rb_intern("y"), 0))); - }else{ - rb_raise(rb_eTypeError, "require %s or compatible object.", rb_class2name(cCvPoint2D32f::rb_class())); } + else { + raise_compatible_typeerror(object, cCvPoint2D32f::rb_class()); + } + throw "Should never reach here"; } __NAMESPACE_END_OPENCV diff --git a/ext/cvpoint3d32f.cpp b/ext/opencv/cvpoint3d32f.cpp similarity index 80% rename from ext/cvpoint3d32f.cpp rename to ext/opencv/cvpoint3d32f.cpp index dd2eacc8..5a3f6469 100644 --- a/ext/cvpoint3d32f.cpp +++ b/ext/opencv/cvpoint3d32f.cpp @@ -7,7 +7,7 @@ Copyright (C) 2005-2008 Masakazu Yonekura ************************************************************/ -#include"cvpoint3d32f.h" +#include "cvpoint3d32f.h" /* * Document-class: OpenCV::CvPoint3D32f * @@ -15,7 +15,7 @@ * X and Y takes the value of the Float. see also CvPoint * * C structure is here, very simple. - * typdef struct CvPoint3D32f{ + * typdef struct CvPoint3D32f { * float x; * float y; * float z; @@ -32,34 +32,6 @@ rb_class() return rb_klass; } -void -define_ruby_class() -{ - if(rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * cvpoint2d32f = rb_define_class_under(opencv, "CvPoint2D32f", rb_cObject); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - VALUE cvpoint2d32f = cCvPoint2D32f::rb_class(); - rb_klass = rb_define_class_under(opencv, "CvPoint3D32f", cvpoint2d32f); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_singleton_method(rb_klass, "compatible?", RUBY_METHOD_FUNC(rb_compatible_q), 1); - rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); - rb_define_method(rb_klass, "x", RUBY_METHOD_FUNC(rb_x), 0); - rb_define_method(rb_klass, "x=", RUBY_METHOD_FUNC(rb_set_x), 1); - rb_define_method(rb_klass, "y", RUBY_METHOD_FUNC(rb_y), 0); - rb_define_method(rb_klass, "y=", RUBY_METHOD_FUNC(rb_set_y), 1); - rb_define_method(rb_klass, "z", RUBY_METHOD_FUNC(rb_z), 0); - rb_define_method(rb_klass, "z=", RUBY_METHOD_FUNC(rb_set_z), 1); - - rb_define_method(rb_klass, "to_s", RUBY_METHOD_FUNC(rb_to_s), 0); - rb_define_method(rb_klass, "to_ary", RUBY_METHOD_FUNC(rb_to_ary), 0); -} - /* * call-seq: * combatible?(obj) @@ -85,7 +57,9 @@ define_ruby_class() VALUE rb_compatible_q(VALUE klass, VALUE object) { - return (rb_respond_to(object, rb_intern("x")) && rb_respond_to(object, rb_intern("y"))) ? Qtrue : Qfalse; + return (rb_respond_to(object, rb_intern("x")) && + rb_respond_to(object, rb_intern("y")) && + rb_respond_to(object, rb_intern("z"))) ? Qtrue : Qfalse; } VALUE @@ -110,30 +84,27 @@ rb_allocate(VALUE klass) VALUE rb_initialize(int argc, VALUE *argv, VALUE self) { - VALUE obj, x, y, z; + CvPoint3D32f *self_ptr = CVPOINT3D32F(self); switch (argc) { case 0: break; - case 1: - obj = argv[0]; - if(rb_compatible_q(rb_klass, obj)) { - CVPOINT3D32F(self)->x = NUM2DBL(rb_funcall(rb_funcall(obj, rb_intern("x"), 0), rb_intern("to_f"), 0)); - CVPOINT3D32F(self)->y = NUM2DBL(rb_funcall(rb_funcall(obj, rb_intern("y"), 0), rb_intern("to_f"), 0)); - CVPOINT3D32F(self)->z = NUM2DBL(rb_funcall(rb_funcall(obj, rb_intern("z"), 0), rb_intern("to_f"), 0)); - }else{ - rb_raise(rb_eArgError, "object is not compatible %s.", rb_class2name(rb_klass)); - } + case 1: { + CvPoint3D32f point = VALUE_TO_CVPOINT3D32F(argv[0]); + self_ptr->x = point.x; + self_ptr->y = point.y; + self_ptr->z = point.z; break; + } case 3: - x = argv[0], y = argv[1], z = argv[2]; - CVPOINT3D32F(self)->x = NUM2DBL(x); - CVPOINT3D32F(self)->y = NUM2DBL(y); - CVPOINT3D32F(self)->z = NUM2DBL(z); + self_ptr->x = NUM2DBL(argv[0]); + self_ptr->y = NUM2DBL(argv[1]); + self_ptr->z = NUM2DBL(argv[2]); break; default: rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc); + break; } - return Qnil; + return self; } /* @@ -213,7 +184,7 @@ rb_to_s(VALUE self) { const int i = 5; VALUE str[i]; - str[0] = rb_str_new2("<%s:(%f,%f,%f)>"); + str[0] = rb_str_new2("<%s:(%g,%g,%g)>"); str[1] = rb_str_new2(rb_class2name(CLASS_OF(self))); str[2] = rb_x(self); str[3] = rb_y(self); @@ -241,5 +212,41 @@ new_object(CvPoint3D32f point) return object; } +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); + VALUE cvpoint2d32f = rb_define_class_under(opencv, "CvPoint2D32f", rb_cObject); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * cvpoint2d32f = rb_define_class_under(opencv, "CvPoint2D32f", rb_cObject); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + VALUE cvpoint2d32f = cCvPoint2D32f::rb_class(); + rb_klass = rb_define_class_under(opencv, "CvPoint3D32f", cvpoint2d32f); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_singleton_method(rb_klass, "compatible?", RUBY_METHOD_FUNC(rb_compatible_q), 1); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "x", RUBY_METHOD_FUNC(rb_x), 0); + rb_define_method(rb_klass, "x=", RUBY_METHOD_FUNC(rb_set_x), 1); + rb_define_method(rb_klass, "y", RUBY_METHOD_FUNC(rb_y), 0); + rb_define_method(rb_klass, "y=", RUBY_METHOD_FUNC(rb_set_y), 1); + rb_define_method(rb_klass, "z", RUBY_METHOD_FUNC(rb_z), 0); + rb_define_method(rb_klass, "z=", RUBY_METHOD_FUNC(rb_set_z), 1); + + rb_define_method(rb_klass, "to_s", RUBY_METHOD_FUNC(rb_to_s), 0); + rb_define_method(rb_klass, "to_ary", RUBY_METHOD_FUNC(rb_to_ary), 0); + rb_define_alias(rb_klass, "to_a", "to_ary"); +} + __NAMESPACE_END_CVPOINT3D32F __NAMESPACE_END_OPENCV + diff --git a/ext/cvpoint3d32f.h b/ext/opencv/cvpoint3d32f.h similarity index 81% rename from ext/cvpoint3d32f.h rename to ext/opencv/cvpoint3d32f.h index d6b4c48c..3d225cfd 100644 --- a/ext/cvpoint3d32f.h +++ b/ext/opencv/cvpoint3d32f.h @@ -10,17 +10,17 @@ #ifndef RUBY_OPENCV_CVPOINT3D32F_H #define RUBY_OPENCV_CVPOINT3D32F_H -#define __NAMESPACE_BEGIN_CVPOINT3D32F namespace cCvPoint3D32f{ +#define __NAMESPACE_BEGIN_CVPOINT3D32F namespace cCvPoint3D32f { #define __NAMESPACE_END_CVPOINT3D32F } -#include"opencv.h" +#include "opencv.h" __NAMESPACE_BEGIN_OPENCV __NAMESPACE_BEGIN_CVPOINT3D32F VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_compatible_q(VALUE klass, VALUE object); @@ -51,13 +51,15 @@ CVPOINT3D32F(VALUE object) inline CvPoint3D32f VALUE_TO_CVPOINT3D32F(VALUE object) { - if(cCvPoint3D32f::rb_compatible_q(cCvPoint3D32f::rb_class(), object)){ + if (cCvPoint3D32f::rb_compatible_q(cCvPoint3D32f::rb_class(), object)) { return cvPoint3D32f(NUM2DBL(rb_funcall(object, rb_intern("x"), 0)), NUM2DBL(rb_funcall(object, rb_intern("y"), 0)), NUM2DBL(rb_funcall(object, rb_intern("z"), 0))); - }else{ - rb_raise(rb_eTypeError, "require %s or compatible object.", rb_class2name(cCvPoint3D32f::rb_class())); } + else { + raise_compatible_typeerror(object, cCvPoint3D32f::rb_class()); + } + throw "Should never reach here"; } __NAMESPACE_END_OPENCV diff --git a/ext/cvrect.cpp b/ext/opencv/cvrect.cpp similarity index 72% rename from ext/cvrect.cpp rename to ext/opencv/cvrect.cpp index 80f67af3..47846b09 100644 --- a/ext/cvrect.cpp +++ b/ext/opencv/cvrect.cpp @@ -15,7 +15,7 @@ * * * C stracture is here, very simple. - * typdef struct CvRect{ + * typdef struct CvRect { * int x; * int y; * int width; @@ -34,40 +34,6 @@ rb_class() return rb_klass; } -void -define_ruby_class() -{ - if(rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - rb_klass = rb_define_class_under(opencv, "CvRect", rb_cObject); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_singleton_method(rb_klass, "compatible?", RUBY_METHOD_FUNC(rb_compatible_q), 1); - rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); - - rb_define_method(rb_klass, "x", RUBY_METHOD_FUNC(rb_x), 0); - rb_define_method(rb_klass, "x=", RUBY_METHOD_FUNC(rb_set_x), 1); - rb_define_method(rb_klass, "y", RUBY_METHOD_FUNC(rb_y), 0); - rb_define_method(rb_klass, "y=", RUBY_METHOD_FUNC(rb_set_y), 1); - rb_define_method(rb_klass, "width", RUBY_METHOD_FUNC(rb_width), 0); - rb_define_method(rb_klass, "width=", RUBY_METHOD_FUNC(rb_set_width), 1); - rb_define_method(rb_klass, "height", RUBY_METHOD_FUNC(rb_height), 0); - rb_define_method(rb_klass, "height=", RUBY_METHOD_FUNC(rb_set_height), 1); - rb_define_method(rb_klass, "center", RUBY_METHOD_FUNC(rb_center), 0); - rb_define_method(rb_klass, "points", RUBY_METHOD_FUNC(rb_points), 0); - rb_define_method(rb_klass, "top_left", RUBY_METHOD_FUNC(rb_top_left), 0); - rb_define_method(rb_klass, "top_right", RUBY_METHOD_FUNC(rb_top_right), 0); - rb_define_method(rb_klass, "bottom_left", RUBY_METHOD_FUNC(rb_bottom_left), 0); - rb_define_method(rb_klass, "bottom_right", RUBY_METHOD_FUNC(rb_bottom_right), 0); - rb_define_method(rb_klass, "or", RUBY_METHOD_FUNC(rb_or), 1); - rb_define_alias(rb_klass, "|", "or"); -} - /* * call-seq: * combatible?(obj) @@ -96,19 +62,22 @@ define_ruby_class() VALUE rb_compatible_q(VALUE klass, VALUE object) { - return (rb_respond_to(object, rb_intern("x")) && rb_respond_to(object, rb_intern("y")) && rb_respond_to(object, rb_intern("width")) && rb_respond_to(object, rb_intern("height"))) ? Qtrue : Qfalse; + return (rb_respond_to(object, rb_intern("x")) && + rb_respond_to(object, rb_intern("y")) && + rb_respond_to(object, rb_intern("width")) && + rb_respond_to(object, rb_intern("height"))) ? Qtrue : Qfalse; } /* * call-seq: - * CvRect.bounding + * max_rect(rect1, rect2) -> cvrect * + * Finds bounding rectangle for given rectangles. */ VALUE -rb_bounding(VALUE klass, VALUE points) +rb_max_rect(VALUE klass, VALUE rect1, VALUE rect2) { - /* not yet */ - return Qnil; + return cCvRect::new_object(cvMaxRect(CVRECT(rect1), CVRECT(rect2))); } VALUE @@ -134,32 +103,29 @@ rb_allocate(VALUE klass) VALUE rb_initialize(int argc, VALUE *argv, VALUE self) { - VALUE object, x, y, width, height; + CvRect *self_ptr = CVRECT(self); switch (argc) { case 0: break; - case 1: - object = argv[0]; - if(rb_compatible_q(rb_klass, object)) { - CVRECT(self)->x = NUM2INT(rb_funcall(rb_funcall(object, rb_intern("x"), 0), rb_intern("to_i"), 0)); - CVRECT(self)->y = NUM2INT(rb_funcall(rb_funcall(object, rb_intern("y"), 0), rb_intern("to_i"), 0)); - CVRECT(self)->width = NUM2INT(rb_funcall(rb_funcall(object, rb_intern("width"), 0), rb_intern("to_i"), 0)); - CVRECT(self)->height = NUM2INT(rb_funcall(rb_funcall(object, rb_intern("height"), 0), rb_intern("to_i"), 0)); - }else{ - rb_raise(rb_eArgError, "object is not compatible %s.", rb_class2name(rb_klass)); - } + case 1: { + CvRect rect = VALUE_TO_CVRECT(argv[0]); + self_ptr->x = rect.x; + self_ptr->y = rect.y; + self_ptr->width = rect.width; + self_ptr->height = rect.height; break; + } case 4: - x = argv[0], y = argv[1], width = argv[2], height = argv[3]; - CVRECT(self)->x = NUM2INT(x); - CVRECT(self)->y = NUM2INT(y); - CVRECT(self)->width = NUM2INT(width); - CVRECT(self)->height = NUM2INT(height); + self_ptr->x = NUM2INT(argv[0]); + self_ptr->y = NUM2INT(argv[1]); + self_ptr->width = NUM2INT(argv[2]); + self_ptr->height = NUM2INT(argv[3]); break; default: rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc); + break; } - return Qnil; + return self; } /* @@ -168,7 +134,7 @@ rb_initialize(int argc, VALUE *argv, VALUE self) VALUE rb_x(VALUE self) { - return INT2FIX(CVRECT(self)->x); + return INT2NUM(CVRECT(self)->x); } /* @@ -191,7 +157,7 @@ rb_set_x(VALUE self, VALUE x) VALUE rb_y(VALUE self) { - return INT2FIX(CVRECT(self)->y); + return INT2NUM(CVRECT(self)->y); } /* @@ -214,7 +180,7 @@ rb_set_y(VALUE self, VALUE y) VALUE rb_width(VALUE self) { - return INT2FIX(CVRECT(self)->width); + return INT2NUM(CVRECT(self)->width); } /* @@ -237,7 +203,7 @@ rb_set_width(VALUE self, VALUE x) VALUE rb_height(VALUE self) { - return INT2FIX(CVRECT(self)->height); + return INT2NUM(CVRECT(self)->height); } /* @@ -286,7 +252,8 @@ rb_points(VALUE self) VALUE rb_top_left(VALUE self) { - return cCvPoint::new_object(cvPoint(CVRECT(self)->x, CVRECT(self)->y)); + CvRect* rect = CVRECT(self); + return cCvPoint::new_object(cvPoint(rect->x, rect->y)); } /* @@ -295,7 +262,8 @@ rb_top_left(VALUE self) VALUE rb_top_right(VALUE self) { - return cCvPoint::new_object(cvPoint(CVRECT(self)->x + CVRECT(self)->width, CVRECT(self)->y)); + CvRect* rect = CVRECT(self); + return cCvPoint::new_object(cvPoint(rect->x + rect->width, rect->y)); } /* @@ -304,7 +272,9 @@ rb_top_right(VALUE self) VALUE rb_bottom_left(VALUE self) { - return cCvPoint::new_object(cvPoint(CVRECT(self)->x, CVRECT(self)->y + CVRECT(self)->height)); + CvRect* rect = CVRECT(self); + return cCvPoint::new_object(cvPoint(rect->x, + rect->y + rect->height)); } /* @@ -313,19 +283,9 @@ rb_bottom_left(VALUE self) VALUE rb_bottom_right(VALUE self) { - return cCvPoint::new_object(cvPoint(CVRECT(self)->x + CVRECT(self)->width, CVRECT(self)->y + CVRECT(self)->height)); -} - -/* - * call-seq: - * or(rect) -> cvrect - * - * Finds bounding rectangle for self and given rectangles. - */ -VALUE -rb_or(VALUE self, VALUE rect) -{ - return cCvRect::new_object(cvMaxRect(CVRECT(self), CVRECT(rect))); + CvRect* rect = CVRECT(self); + return cCvPoint::new_object(cvPoint(rect->x + rect->width, + rect->y + rect->height)); } VALUE @@ -336,5 +296,43 @@ new_object(CvRect rect) return object; } +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + rb_klass = rb_define_class_under(opencv, "CvRect", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_singleton_method(rb_klass, "compatible?", RUBY_METHOD_FUNC(rb_compatible_q), 1); + rb_define_singleton_method(rb_klass, "max_rect", RUBY_METHOD_FUNC(rb_max_rect), 2); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + + rb_define_method(rb_klass, "x", RUBY_METHOD_FUNC(rb_x), 0); + rb_define_method(rb_klass, "x=", RUBY_METHOD_FUNC(rb_set_x), 1); + rb_define_method(rb_klass, "y", RUBY_METHOD_FUNC(rb_y), 0); + rb_define_method(rb_klass, "y=", RUBY_METHOD_FUNC(rb_set_y), 1); + rb_define_method(rb_klass, "width", RUBY_METHOD_FUNC(rb_width), 0); + rb_define_method(rb_klass, "width=", RUBY_METHOD_FUNC(rb_set_width), 1); + rb_define_method(rb_klass, "height", RUBY_METHOD_FUNC(rb_height), 0); + rb_define_method(rb_klass, "height=", RUBY_METHOD_FUNC(rb_set_height), 1); + rb_define_method(rb_klass, "center", RUBY_METHOD_FUNC(rb_center), 0); + rb_define_method(rb_klass, "points", RUBY_METHOD_FUNC(rb_points), 0); + rb_define_method(rb_klass, "top_left", RUBY_METHOD_FUNC(rb_top_left), 0); + rb_define_method(rb_klass, "top_right", RUBY_METHOD_FUNC(rb_top_right), 0); + rb_define_method(rb_klass, "bottom_left", RUBY_METHOD_FUNC(rb_bottom_left), 0); + rb_define_method(rb_klass, "bottom_right", RUBY_METHOD_FUNC(rb_bottom_right), 0); +} + __NAMESPACE_END_CVRECT __NAMESPACE_END_OPENCV diff --git a/ext/cvrect.h b/ext/opencv/cvrect.h similarity index 82% rename from ext/cvrect.h rename to ext/opencv/cvrect.h index 3686155b..8f54b2cd 100644 --- a/ext/cvrect.h +++ b/ext/opencv/cvrect.h @@ -10,9 +10,9 @@ #ifndef RUBY_OPENCV_CVRECT_H #define RUBY_OPENCV_CVRECT_H -#include"opencv.h" +#include "opencv.h" -#define __NAMESPACE_BEGIN_CVRECT namespace cCvRect{ +#define __NAMESPACE_BEGIN_CVRECT namespace cCvRect { #define __NAMESPACE_END_CVRECT } __NAMESPACE_BEGIN_OPENCV @@ -20,10 +20,10 @@ __NAMESPACE_BEGIN_CVRECT VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_compatible_q(VALUE klass, VALUE object); -VALUE rb_bounding(VALUE klass, VALUE points); +VALUE rb_max_rect(VALUE klass, VALUE rect1, VALUE rect2); VALUE rb_allocate(VALUE klass); VALUE rb_initialize(int argc, VALUE *argv, VALUE self); @@ -47,8 +47,6 @@ VALUE rb_set_bottom_left(VALUE self, VALUE point); VALUE rb_bottom_right(VALUE self); VALUE rb_set_bottom_right(VALUE self, VALUE point); -VALUE rb_or(VALUE self, VALUE rect); - VALUE new_object(CvRect rect); __NAMESPACE_END_CVRECT @@ -64,14 +62,16 @@ CVRECT(VALUE object) inline CvRect VALUE_TO_CVRECT(VALUE object) { - if(cCvRect::rb_compatible_q(cCvRect::rb_class(), object)){ + if (cCvRect::rb_compatible_q(cCvRect::rb_class(), object)) { return cvRect(NUM2INT(rb_funcall(object, rb_intern("x"), 0)), NUM2INT(rb_funcall(object, rb_intern("y"), 0)), NUM2INT(rb_funcall(object, rb_intern("width"), 0)), NUM2INT(rb_funcall(object, rb_intern("height"), 0))); - }else{ - rb_raise(rb_eTypeError, "require %s or compatible object.", rb_class2name(cCvRect::rb_class())); } + else { + raise_compatible_typeerror(object, cCvRect::rb_class()); + } + throw "Should never reach here"; } __NAMESPACE_END_OPENCV diff --git a/ext/cvscalar.cpp b/ext/opencv/cvscalar.cpp similarity index 84% rename from ext/cvscalar.cpp rename to ext/opencv/cvscalar.cpp index 0b4923b5..14ccf11d 100644 --- a/ext/cvscalar.cpp +++ b/ext/opencv/cvscalar.cpp @@ -16,9 +16,9 @@ * Therefore, CvScalar has 4-values. * * C structure is here, very simple. - * typdef struct CvScalar{ + * typdef struct CvScalar { * double val[4]; - * }CvScalar; + * } CvScalar; * * If obtain CvScalar-object from the method of CvMat(or IplImage), * the channel outside the range is obtained as all 0. @@ -42,49 +42,6 @@ rb_class() return rb_klass; } -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - rb_klass = rb_define_class_under(opencv, "CvScalar", rb_cObject); - /* CvScalar: class */ - rb_define_const(opencv, "CvColor", rb_klass); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); - rb_define_method(rb_klass, "[]", RUBY_METHOD_FUNC(rb_aref), 1); - rb_define_method(rb_klass, "[]=", RUBY_METHOD_FUNC(rb_aset), 2); - rb_define_method(rb_klass, "sub", RUBY_METHOD_FUNC(rb_sub), -1); - rb_define_alias(rb_klass, "-", "sub"); - - rb_define_method(rb_klass, "to_s", RUBY_METHOD_FUNC(rb_to_s), 0); - rb_define_method(rb_klass, "to_ary", RUBY_METHOD_FUNC(rb_to_ary), 0); - - rb_define_const(rb_klass, "Black", cCvScalar::new_object(cvScalar(0x0,0x0,0x0))); - rb_define_const(rb_klass, "Silver", cCvScalar::new_object(cvScalar(0x0c,0x0c,0x0c))); - rb_define_const(rb_klass, "Gray", cCvScalar::new_object(cvScalar(0x80,0x80,0x80))); - rb_define_const(rb_klass, "White", cCvScalar::new_object(cvScalar(0xff,0xff,0xff))); - rb_define_const(rb_klass, "Maroon", cCvScalar::new_object(cvScalar(0x0,0x0,0x80))); - rb_define_const(rb_klass, "Red", cCvScalar::new_object(cvScalar(0x0,0x0,0xff))); - rb_define_const(rb_klass, "Purple", cCvScalar::new_object(cvScalar(0x80,0x0,0x80))); - rb_define_const(rb_klass, "Fuchsia", cCvScalar::new_object(cvScalar(0xff,0x0,0xff))); - rb_define_const(rb_klass, "Green", cCvScalar::new_object(cvScalar(0x0,0x80,0x0))); - rb_define_const(rb_klass, "Lime", cCvScalar::new_object(cvScalar(0x0,0xff,0x0))); - rb_define_const(rb_klass, "Olive", cCvScalar::new_object(cvScalar(0x0,0x80,0x80))); - rb_define_const(rb_klass, "Yellow", cCvScalar::new_object(cvScalar(0x0,0xff,0xff))); - rb_define_const(rb_klass, "Navy", cCvScalar::new_object(cvScalar(0x80,0x0,0x0))); - rb_define_const(rb_klass, "Blue", cCvScalar::new_object(cvScalar(0xff,0x0,0x0))); - rb_define_const(rb_klass, "Teal", cCvScalar::new_object(cvScalar(0x80,0x80,0x0))); - rb_define_const(rb_klass, "Aqua", cCvScalar::new_object(cvScalar(0xff,0xff,0x0))); -} - VALUE rb_allocate(VALUE klass) { @@ -94,17 +51,18 @@ rb_allocate(VALUE klass) /* * call-seq: - * new([d1][,d2][,d3][,d4]) + * new([d1][,d2][,d3][,d4]) * - * Create new Scalar. Argument should be Fixnum (or nil as 0). + * Create new Scalar. Argument should be Integer (or nil as 0). */ VALUE rb_initialize(int argc, VALUE *argv, VALUE self) { VALUE val[4]; rb_scan_args(argc, argv, "04", &val[0], &val[1], &val[2], &val[3]); - for (int i = 0; i < 4; i++) { - CVSCALAR(self)->val[i] = NIL_P(val[i]) ? 0 : NUM2DBL(val[i]); + CvScalar* self_ptr = CVSCALAR(self); + for (int i = 0; i < 4; ++i) { + self_ptr->val[i] = NIL_P(val[i]) ? 0 : NUM2DBL(val[i]); } return self; } @@ -119,11 +77,10 @@ VALUE rb_aref(VALUE self, VALUE index) { int idx = NUM2INT(index); - if (!(idx < 0) && idx < 4) { - return rb_float_new(CVSCALAR(self)->val[idx]); - }else{ + if (idx < 0 || idx >= 4) { rb_raise(rb_eIndexError, "scalar index should be 0...4"); } + return rb_float_new(CVSCALAR(self)->val[idx]); } /* @@ -136,12 +93,11 @@ VALUE rb_aset(VALUE self, VALUE index, VALUE value) { int idx = NUM2INT(index); - if (!(idx < 0) && idx < 4) { - CVSCALAR(self)->val[idx] = NUM2DBL(value); - return self; - }else{ + if (idx < 0 || idx >= 4) { rb_raise(rb_eIndexError, "scalar index should be 0...4"); } + CVSCALAR(self)->val[idx] = NUM2DBL(value); + return self; } /* @@ -157,12 +113,21 @@ rb_sub(int argc, VALUE *argv, VALUE self) { VALUE val, mask; rb_scan_args(argc, argv, "11", &val, &mask); - if(rb_obj_is_kind_of(val, cCvMat::rb_class())){ - VALUE dest = cCvMat::new_object(cvGetSize(CVARR(val)), cvGetElemType(CVARR(val))); - cvSubRS(CVARR(val), *CVSCALAR(self), CVARR(dest), MASK(mask)); + if (rb_obj_is_kind_of(val, cCvMat::rb_class())) { + CvArr *val_ptr = CVARR(val); + VALUE dest = Qnil; + try { + dest = cCvMat::new_object(cvGetSize(val_ptr), cvGetElemType(val_ptr)); + cvSubRS(val_ptr, *CVSCALAR(self), CVARR(dest), MASK(mask)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } return dest; - }else{ - CvScalar *src = CVSCALAR(self), scl = VALUE_TO_CVSCALAR(val); + } + else { + CvScalar *src = CVSCALAR(self); + CvScalar scl = VALUE_TO_CVSCALAR(val); return new_object(cvScalar(src->val[0] - scl.val[0], src->val[1] - scl.val[1], src->val[2] - scl.val[2], @@ -181,7 +146,7 @@ rb_to_s(VALUE self) { const int i = 6; VALUE str[i]; - str[0] = rb_str_new2("<%s:%d,%d,%d,%d>"); + str[0] = rb_str_new2("<%s:%g,%g,%g,%g>"); str[1] = rb_str_new2(rb_class2name(CLASS_OF(self))); str[2] = rb_aref(self, INT2FIX(0)); str[3] = rb_aref(self, INT2FIX(1)); @@ -222,6 +187,55 @@ new_object(CvScalar scalar) return object; } +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + + rb_klass = rb_define_class_under(opencv, "CvScalar", rb_cObject); + /* CvScalar: class */ + rb_define_const(opencv, "CvColor", rb_klass); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "[]", RUBY_METHOD_FUNC(rb_aref), 1); + rb_define_method(rb_klass, "[]=", RUBY_METHOD_FUNC(rb_aset), 2); + rb_define_method(rb_klass, "sub", RUBY_METHOD_FUNC(rb_sub), -1); + rb_define_alias(rb_klass, "-", "sub"); + + rb_define_method(rb_klass, "to_s", RUBY_METHOD_FUNC(rb_to_s), 0); + rb_define_method(rb_klass, "to_ary", RUBY_METHOD_FUNC(rb_to_ary), 0); + rb_define_alias(rb_klass, "to_a", "to_ary"); + + rb_define_const(rb_klass, "Black", cCvScalar::new_object(cvScalar(0x0,0x0,0x0))); + rb_define_const(rb_klass, "Silver", cCvScalar::new_object(cvScalar(0x0c,0x0c,0x0c))); + rb_define_const(rb_klass, "Gray", cCvScalar::new_object(cvScalar(0x80,0x80,0x80))); + rb_define_const(rb_klass, "White", cCvScalar::new_object(cvScalar(0xff,0xff,0xff))); + rb_define_const(rb_klass, "Maroon", cCvScalar::new_object(cvScalar(0x0,0x0,0x80))); + rb_define_const(rb_klass, "Red", cCvScalar::new_object(cvScalar(0x0,0x0,0xff))); + rb_define_const(rb_klass, "Purple", cCvScalar::new_object(cvScalar(0x80,0x0,0x80))); + rb_define_const(rb_klass, "Fuchsia", cCvScalar::new_object(cvScalar(0xff,0x0,0xff))); + rb_define_const(rb_klass, "Green", cCvScalar::new_object(cvScalar(0x0,0x80,0x0))); + rb_define_const(rb_klass, "Lime", cCvScalar::new_object(cvScalar(0x0,0xff,0x0))); + rb_define_const(rb_klass, "Olive", cCvScalar::new_object(cvScalar(0x0,0x80,0x80))); + rb_define_const(rb_klass, "Yellow", cCvScalar::new_object(cvScalar(0x0,0xff,0xff))); + rb_define_const(rb_klass, "Navy", cCvScalar::new_object(cvScalar(0x80,0x0,0x0))); + rb_define_const(rb_klass, "Blue", cCvScalar::new_object(cvScalar(0xff,0x0,0x0))); + rb_define_const(rb_klass, "Teal", cCvScalar::new_object(cvScalar(0x80,0x80,0x0))); + rb_define_const(rb_klass, "Aqua", cCvScalar::new_object(cvScalar(0xff,0xff,0x0))); +} + __NAMESPACE_END_CVSCALAR __NAMESPACE_END_OPENCV diff --git a/ext/cvscalar.h b/ext/opencv/cvscalar.h similarity index 66% rename from ext/cvscalar.h rename to ext/opencv/cvscalar.h index 381448a1..fcdcc812 100644 --- a/ext/cvscalar.h +++ b/ext/opencv/cvscalar.h @@ -12,7 +12,7 @@ #include "opencv.h" -#define __NAMESPACE_BEGIN_CVSCALAR namespace cCvScalar{ +#define __NAMESPACE_BEGIN_CVSCALAR namespace cCvScalar { #define __NAMESPACE_END_CVSCALAR } __NAMESPACE_BEGIN_OPENCV @@ -20,7 +20,7 @@ __NAMESPACE_BEGIN_CVSCALAR VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_compatible_q(VALUE klass, VALUE object); @@ -50,12 +50,20 @@ CVSCALAR(VALUE object) inline CvScalar VALUE_TO_CVSCALAR(VALUE object) { - if(FIXNUM_P(object)) + ID aref_id; + if (FIXNUM_P(object)) { return cvScalarAll(FIX2INT(object)); - return cvScalar(NUM2INT(rb_funcall(object, rb_intern("[]"), 1, INT2FIX(0))), - NUM2INT(rb_funcall(object, rb_intern("[]"), 1, INT2FIX(1))), - NUM2INT(rb_funcall(object, rb_intern("[]"), 1, INT2FIX(2))), - NUM2INT(rb_funcall(object, rb_intern("[]"), 1, INT2FIX(3)))); + } + else if (rb_respond_to(object, (aref_id = rb_intern("[]")))) { + return cvScalar(NUM2DBL(rb_funcall(object, aref_id, 1, INT2FIX(0))), + NUM2DBL(rb_funcall(object, aref_id, 1, INT2FIX(1))), + NUM2DBL(rb_funcall(object, aref_id, 1, INT2FIX(2))), + NUM2DBL(rb_funcall(object, aref_id, 1, INT2FIX(3)))); + } + else { + raise_compatible_typeerror(object, cCvScalar::rb_class()); + } + throw "Should never reach here"; } __NAMESPACE_END_OPENCV diff --git a/ext/opencv/cvseq.cpp b/ext/opencv/cvseq.cpp new file mode 100644 index 00000000..ac362222 --- /dev/null +++ b/ext/opencv/cvseq.cpp @@ -0,0 +1,663 @@ +/************************************************************ + + cvseq.cpp - + + $Author: lsxi $ + + Copyright (C) 2005-2006 Masakazu Yonekura + +************************************************************/ +#include "cvseq.h" +/* + * Document-class: OpenCV::CvSeq + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVSEQ + +VALUE rb_allocate(VALUE klass); +void cvseq_free(void *ptr); + +VALUE rb_klass; +// contain sequence-block class +st_table *seqblock_klass_table = st_init_numtable(); + +VALUE +rb_class() +{ + return rb_klass; +} + +int +eltype2class(int eltype, VALUE* ret) { + int found = 1; + + switch (eltype) { + case CV_SEQ_ELTYPE_POINT: + *ret = cCvPoint::rb_class(); + break; + case CV_32FC2: + *ret = cCvPoint2D32f::rb_class(); + break; + case CV_SEQ_ELTYPE_POINT3D: + *ret = cCvPoint3D32f::rb_class(); + break; + case CV_SEQ_ELTYPE_CODE: + case CV_SEQ_ELTYPE_INDEX: + *ret = rb_cInteger; + break; + case CV_SEQ_ELTYPE_PPOINT: // or CV_SEQ_ELTYPE_PTR: + // Not supported + rb_raise(rb_eArgError, "seq_flags %d is not supported.", eltype); + break; + default: + found = 0; + *ret = cCvPoint::rb_class(); + break; + } + + return found; +} + +VALUE +seqblock_class(void *ptr) +{ + VALUE klass = Qnil; + if (st_lookup(seqblock_klass_table, (st_data_t)ptr, (st_data_t*)&klass)) { + return klass; + } + + int eltype = CV_SEQ_ELTYPE((CvSeq*)ptr); + eltype2class(eltype, &klass); + + return klass; +} + +void +register_elem_class(CvSeq *seq, VALUE klass) +{ + st_insert(seqblock_klass_table, (st_data_t)seq, (st_data_t)klass); +} + +void +unregister_elem_class(void *ptr) +{ + if (ptr) { + st_delete(seqblock_klass_table, (st_data_t*)&ptr, NULL); + unregister_object(ptr); + } +} + +VALUE +rb_allocate(VALUE klass) +{ + CvSeq *ptr = ALLOC(CvSeq); + return Data_Wrap_Struct(klass, mark_root_object, unregister_elem_class, ptr); +} + +CvSeq* +create_seq(int seq_flags, size_t header_size, VALUE storage_value) +{ + VALUE klass = Qnil; + int eltype = seq_flags & CV_SEQ_ELTYPE_MASK; + storage_value = CHECK_CVMEMSTORAGE(storage_value); + + if (!eltype2class(eltype, &klass)) { + seq_flags = CV_SEQ_ELTYPE_POINT | CV_SEQ_KIND_GENERIC; + } + + int mat_type = CV_MAT_TYPE(seq_flags); + size_t elem_size = (size_t)(CV_ELEM_SIZE(mat_type)); + CvSeq* seq = NULL; + try { + seq = cvCreateSeq(seq_flags, header_size, elem_size, CVMEMSTORAGE(storage_value)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + register_elem_class(seq, klass); + register_root_object(seq, storage_value); + + return seq; +} + +VALUE +class2seq_flags_value(VALUE klass) { + int seq_flags; + if (klass == cCvPoint::rb_class()) { + seq_flags = CV_SEQ_ELTYPE_POINT; + } + else if (klass == cCvPoint2D32f::rb_class()) { + seq_flags = CV_32FC2; + } + else if (klass == cCvPoint3D32f::rb_class()) { + seq_flags = CV_SEQ_ELTYPE_POINT3D; + } + else if (klass == rb_cInteger) { + seq_flags = CV_SEQ_ELTYPE_INDEX; + } + else { + rb_raise(rb_eTypeError, "unexpected type: %s", rb_class2name(klass)); + } + + return INT2NUM(seq_flags | CV_SEQ_KIND_GENERIC); +} + +/* + * Constructor + * + * @overload new(seq_flags, storage = nil) + * @param [Integer] seq_flags Flags of the created sequence, which are combinations of + * the element types and sequence types. + * - Element type: + * - CV_SEQ_ELTYPE_POINT: {CvPoint} + * - CV_32FC2: {CvPoint2D32f} + * - CV_SEQ_ELTYPE_POINT3D: {CvPoint3D32f} + * - CV_SEQ_ELTYPE_INDEX: Integer + * - CV_SEQ_ELTYPE_CODE: Integer (Freeman code) + * - Sequence type: + * - CV_SEQ_KIND_GENERIC: Generic sequence + * - CV_SEQ_KIND_CURVE: Curve + * @param [CvMemStorage] storage Sequence location + * @return [CvSeq] self + * @opencv_func cvCreateSeq + * @example + * seq1 = CvSeq.new(CV_SEQ_ELTYPE_INDEX) + * seq1 << 1 + * seq1 << CvPoint.new(1, 2) #=> TypeError + * + * seq2 = CvSeq.new(CV_SEQ_ELTYPE_POINT | CV_SEQ_KIND_CURVE) + * seq2 << CvPoint.new(1, 2) + * seq2 << 3 #=> TypeError + */ +VALUE +rb_initialize(int argc, VALUE *argv, VALUE self) +{ + VALUE seq_flags_value, storage_value; + rb_scan_args(argc, argv, "11", &seq_flags_value, &storage_value); + int seq_flags = 0; + + if (TYPE(seq_flags_value) == T_CLASS) { // To maintain backward compatibility + seq_flags_value = class2seq_flags_value(seq_flags_value); + } + Check_Type(seq_flags_value, T_FIXNUM); + seq_flags = FIX2INT(seq_flags_value); + + DATA_PTR(self) = create_seq(seq_flags, sizeof(CvSeq), storage_value); + + return self; +} + +/* + * call-seq: + * total -> int + * + * Return total number of sequence-block. + */ +VALUE +rb_total(VALUE self) +{ + return INT2NUM(CVSEQ(self)->total); +} + +/* + * call-seq: + * empty? -> true or false. + * + * Return true if contain no object, otherwize return false. + */ +VALUE +rb_empty_q(VALUE self) +{ + return CVSEQ(self)->total == 0 ? Qtrue : Qfalse; +} + +/* + * call-seq: + * [index] -> obj or nil + * + * Return sequence-block at index. + */ +VALUE +rb_aref(VALUE self, VALUE index) +{ + CvSeq *seq = CVSEQ(self); + int idx = NUM2INT(index); + if (seq->total == 0) { + return Qnil; + } + if (idx >= seq->total) { + rb_raise(rb_eIndexError, "index %d out of sequence", idx); + } + + VALUE result = Qnil; + try { + VALUE klass = seqblock_class(seq); + if (RTEST(rb_class_inherited_p(klass, rb_cInteger))) { + result = INT2NUM(*CV_GET_SEQ_ELEM(int, seq, idx)); + } + else { + result = REFER_OBJECT(klass, cvGetSeqElem(seq, idx), self); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return result; +} + +/* + * call-seq: + * first -> obj or nil + * + * Return first sequence-block. + */ +VALUE +rb_first(VALUE self) +{ + return rb_aref(self, INT2FIX(0)); +} + +/* + * call-seq: + * last -> obj or nil + * + * Return last sequence-block. + */ +VALUE +rb_last(VALUE self) +{ + return rb_aref(self, INT2FIX(-1)); +} + +/* + * call-seq: + * h_prev -> seq or nil + * + * Return the sequence horizontally located in previous. + * Return nil if not existing. + */ +VALUE +rb_h_prev(VALUE self) +{ + CvSeq *seq = CVSEQ(self); + if (seq->h_prev) + return new_sequence(CLASS_OF(self), seq->h_prev, seqblock_class(seq), lookup_root_object(seq)); + else + return Qnil; +} + +/* + * call-seq: + * h_next -> seq or nil + * + * Return the sequence horizontally located in next. + * Return nil if not existing. + */ +VALUE +rb_h_next(VALUE self) +{ + CvSeq *seq = CVSEQ(self); + if (seq->h_next) + return new_sequence(CLASS_OF(self), seq->h_next, seqblock_class(seq), lookup_root_object(seq)); + else + return Qnil; +} + +/* + * call-seq: + * v_prev -> seq or nil + * + * Return the sequence vertically located in previous. + * Return nil if not existing. + */ +VALUE +rb_v_prev(VALUE self) +{ + CvSeq *seq = CVSEQ(self); + if (seq->v_prev) + return new_sequence(CLASS_OF(self), seq->v_prev, seqblock_class(seq), lookup_root_object(seq)); + else + return Qnil; +} + +/* + * call-seq: + * v_next -> seq or nil + * + * Return the sequence vertically located in next. + * Return nil if not existing. + */ +VALUE +rb_v_next(VALUE self) +{ + CvSeq *seq = CVSEQ(self); + if (seq->v_next) + return new_sequence(CLASS_OF(self), seq->v_next, seqblock_class(seq), lookup_root_object(seq)); + else + return Qnil; +} + +VALUE +rb_seq_push(VALUE self, VALUE args, int flag) +{ + CvSeq *seq = CVSEQ(self); + VALUE klass = seqblock_class(seq); + volatile void *elem = NULL; + int len = RARRAY_LEN(args); + for (int i = 0; i < len; i++) { + VALUE object = RARRAY_PTR(args)[i]; + if (rb_obj_is_kind_of(object, klass)) { + if (rb_obj_is_kind_of(object, rb_cInteger)) { + volatile int int_elem = NUM2INT(object); + elem = &int_elem; + } + else if (rb_obj_is_kind_of(object, rb_cNumeric)) { + volatile double double_elem = NUM2DBL(object); + elem = &double_elem; + } + else { + elem = (void*)DATA_PTR(object); + } + try { + if (flag == CV_FRONT) + cvSeqPushFront(seq, (const void*)elem); + else + cvSeqPush(seq, (const void*)elem); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + } + else if ((rb_obj_is_kind_of(object, rb_klass) == Qtrue) && + RTEST(rb_class_inherited_p(seqblock_class(CVSEQ(object)), klass))) { // object is CvSeq + void *buffer = NULL; + try { + buffer = cvCvtSeqToArray(CVSEQ(object), rb_cvAlloc(CVSEQ(object)->total * CVSEQ(object)->elem_size)); + cvSeqPushMulti(seq, buffer, CVSEQ(object)->total, flag); + cvFree(&buffer); + } + catch (cv::Exception& e) { + if (buffer != NULL) + cvFree(&buffer); + raise_cverror(e); + } + } + else { + rb_raise(rb_eTypeError, "arguments should be %s or %s which includes %s.", + rb_class2name(klass), rb_class2name(rb_klass), rb_class2name(klass)); + } + } + + return self; +} + +/* + * call-seq: + * push(obj, ...) -> self + * + * Append - Pushes the given object(s) on the end of this sequence. This expression return the sequence itself, + * so several append may be chained together. + */ +VALUE +rb_push(VALUE self, VALUE args) +{ + return rb_seq_push(self, args, CV_BACK); +} + +/* + * call-seq: + * pop -> obj or nil + * + * Remove the last sequence-block from self and return it, + * or nil if the sequence is empty. + */ +VALUE +rb_pop(VALUE self) +{ + CvSeq *seq = CVSEQ(self); + if (seq->total == 0) + return Qnil; + + VALUE object = Qnil; + VALUE klass = seqblock_class(seq); + try { + if (klass == rb_cInteger) { + int n = 0; + cvSeqPop(seq, &n); + object = INT2FIX(n); + } + else { + object = GENERIC_OBJECT(klass, malloc(seq->elem_size)); + cvSeqPop(seq, DATA_PTR(object)); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return object; +} + +/* + * call-seq: + * clear -> self + * + * Clears sequence. Removes all elements from the sequence. + */ +VALUE +rb_clear(VALUE self) +{ + try { + cvClearSeq(CVSEQ(self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * call-seq: + * unshift -> self + * + * Prepends objects to the front of sequence. other elements up one. + */ +VALUE +rb_unshift(VALUE self, VALUE args) +{ + VALUE result = Qnil; + try { + result = rb_seq_push(self, args, CV_FRONT); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return result; +} + +/* + * call-seq: + * shift -> obj or nil + * + * Returns the first element of self and removes it (shifting all other elements down by one). Returns nil if the array is empty. + */ +VALUE +rb_shift(VALUE self) +{ + CvSeq *seq = CVSEQ(self); + if (seq->total == 0) + return Qnil; + + VALUE object = Qnil; + try { + if (seqblock_class(seq) == rb_cInteger) { + int n = 0; + cvSeqPopFront(seq, &n); + object = INT2NUM(n); + } + else { + object = GENERIC_OBJECT(seqblock_class(seq), malloc(seq->elem_size)); + cvSeqPopFront(seq, DATA_PTR(object)); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return object; +} + +/* + * call-seq: + * each {|obj| ... } -> self + * + * Calls block once for each sequence-block in self, + * passing that sequence-block as a parameter. + * seq = CvSeq.new(CvIndex) + * seq.push(5, 6, 7) + * seq.each {|x| print x, " -- " } + * produces: + * 5 -- 6 -- 7 -- + */ +VALUE +rb_each(VALUE self) +{ + CvSeq *seq = CVSEQ(self); + if (seq->total > 0) { + VALUE klass = seqblock_class(seq); + try { + if (klass == rb_cInteger) + for (int i = 0; i < seq->total; ++i) + rb_yield(INT2NUM(*CV_GET_SEQ_ELEM(int, seq, i))); + else + for (int i = 0; i < seq->total; ++i) + rb_yield(REFER_OBJECT(klass, cvGetSeqElem(seq, i), self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + } + return self; +} + +/* + * call-seq: + * each_index {|index| ... } -> self + * + * Same as CvSeq#each, but passes the index of the element instead of the element itself. + */ +VALUE +rb_each_index(VALUE self) +{ + CvSeq *seq = CVSEQ(self); + for(int i = 0; i < seq->total; ++i) + rb_yield(INT2NUM(i)); + return self; +} + + +/* + * call-seq: + * insert(index,obj) -> self + * + * Inserts the given values before element with the given index (which may be negative). + */ +VALUE +rb_insert(VALUE self, VALUE index, VALUE object) +{ + Check_Type(index, T_FIXNUM); + CvSeq *seq = CVSEQ(self); + VALUE klass = seqblock_class(seq); + if (!rb_obj_is_kind_of(object, klass)) + rb_raise(rb_eTypeError, "arguments should be %s.", rb_class2name(klass)); + try { + if (klass == rb_cInteger) { + int n = NUM2INT(object); + cvSeqInsert(seq, NUM2INT(index), &n); + } + else + cvSeqInsert(seq, NUM2INT(index), DATA_PTR(object)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * call-seq: + * remove(index) -> obj or nil + * + * Deletes the elements at the specified index. + */ +VALUE +rb_remove(VALUE self, VALUE index) +{ + try { + cvSeqRemove(CVSEQ(self), NUM2INT(index)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +VALUE +new_sequence(VALUE klass, CvSeq *seq, VALUE element_klass, VALUE storage) +{ + register_root_object(seq, storage); + if (!NIL_P(element_klass)) + register_elem_class(seq, element_klass); + return Data_Wrap_Struct(klass, mark_root_object, unregister_elem_class, seq); +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + rb_klass = rb_define_class_under(opencv, "CvSeq", rb_cObject); + rb_include_module(rb_klass, rb_mEnumerable); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "total", RUBY_METHOD_FUNC(rb_total), 0); + rb_define_alias(rb_klass, "length", "total"); + rb_define_alias(rb_klass, "size", "total"); + rb_define_method(rb_klass, "empty?", RUBY_METHOD_FUNC(rb_empty_q), 0); + rb_define_method(rb_klass, "[]", RUBY_METHOD_FUNC(rb_aref), 1); + rb_define_method(rb_klass, "first", RUBY_METHOD_FUNC(rb_first), 0); + rb_define_method(rb_klass, "last", RUBY_METHOD_FUNC(rb_last), 0); + + rb_define_method(rb_klass, "h_prev", RUBY_METHOD_FUNC(rb_h_prev), 0); + rb_define_method(rb_klass, "h_next", RUBY_METHOD_FUNC(rb_h_next), 0); + rb_define_method(rb_klass, "v_prev", RUBY_METHOD_FUNC(rb_v_prev), 0); + rb_define_method(rb_klass, "v_next", RUBY_METHOD_FUNC(rb_v_next), 0); + + rb_define_method(rb_klass, "push", RUBY_METHOD_FUNC(rb_push), -2); + rb_define_alias(rb_klass, "<<", "push"); + rb_define_method(rb_klass, "pop", RUBY_METHOD_FUNC(rb_pop), 0); + rb_define_method(rb_klass, "unshift", RUBY_METHOD_FUNC(rb_unshift), -2); + rb_define_alias(rb_klass, "push_front", "unshift"); + rb_define_method(rb_klass, "shift", RUBY_METHOD_FUNC(rb_shift), 0); + rb_define_alias(rb_klass, "pop_front", "shift"); + rb_define_method(rb_klass, "each", RUBY_METHOD_FUNC(rb_each), 0); + rb_define_method(rb_klass, "each_index", RUBY_METHOD_FUNC(rb_each_index), 0); + rb_define_method(rb_klass, "insert", RUBY_METHOD_FUNC(rb_insert), 2); + rb_define_method(rb_klass, "remove", RUBY_METHOD_FUNC(rb_remove), 1); + rb_define_alias(rb_klass, "delete_at", "remove"); + rb_define_method(rb_klass, "clear", RUBY_METHOD_FUNC(rb_clear), 0); +} + +__NAMESPACE_END_CVSEQ +__NAMESPACE_END_OPENCV + diff --git a/ext/cvseq.h b/ext/opencv/cvseq.h similarity index 77% rename from ext/cvseq.h rename to ext/opencv/cvseq.h index 2acc5a7f..d4e4172f 100644 --- a/ext/cvseq.h +++ b/ext/opencv/cvseq.h @@ -12,20 +12,21 @@ #include "opencv.h" -#define __NAMESPACE_BEGIN_CVSEQ namespace cCvSeq{ +#define __NAMESPACE_BEGIN_CVSEQ namespace cCvSeq { #define __NAMESPACE_END_CVSEQ } __NAMESPACE_BEGIN_OPENCV __NAMESPACE_BEGIN_CVSEQ VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE seqblock_class(void *ptr); +void register_elem_class(CvSeq *seq, VALUE klass); +void unregister_elem_class(void *ptr); +CvSeq* create_seq(int seq_flags, size_t header_size, VALUE storage_value); VALUE rb_allocate(VALUE klass); -void free(void *ptr); -void resist_class_information_of_sequence(CvSeq *seq, VALUE klass); VALUE rb_initialize(int argc, VALUE *argv, VALUE self); VALUE rb_total(VALUE self); @@ -33,7 +34,6 @@ VALUE rb_empty_q(VALUE self); VALUE rb_aref(VALUE self, VALUE index); VALUE rb_first(VALUE self); VALUE rb_last(VALUE self); -VALUE rb_index(VALUE self, VALUE object); VALUE rb_h_prev(VALUE self); VALUE rb_h_next(VALUE self); VALUE rb_v_prev(VALUE self); @@ -44,17 +44,13 @@ VALUE rb_unshift(VALUE self, VALUE args); VALUE rb_shift(VALUE self); VALUE rb_each(VALUE self); VALUE rb_each_index(VALUE self); -VALUE rb_each_with_index(VALUE self); VALUE rb_insert(VALUE self, VALUE index, VALUE object); VALUE rb_remove(VALUE self, VALUE index); VALUE rb_clear(VALUE self); -VALUE rb_clone(VALUE self); VALUE new_object(CvSeq *seq, VALUE klass); VALUE new_object(CvSeq *seq, VALUE klass, VALUE storage); -//VALUE new_object(CvSeq *seq, VALUE storage, VALUE klass); VALUE new_sequence(VALUE klass, CvSeq *seq, VALUE element_klass, VALUE storage); -VALUE auto_extend(VALUE object); __NAMESPACE_END_CVSEQ @@ -66,6 +62,14 @@ CVSEQ(VALUE object) return ptr; } +inline CvSeq* +CVSEQ_WITH_CHECK(VALUE object) +{ + if (!rb_obj_is_kind_of(object, cCvSeq::rb_class())) + raise_typeerror(object, cCvSeq::rb_class()); + return CVSEQ(object); +} + __NAMESPACE_END_OPENCV #endif // RUBY_OPENCV_CVSEQ_H diff --git a/ext/cvsize.cpp b/ext/opencv/cvsize.cpp similarity index 81% rename from ext/cvsize.cpp rename to ext/opencv/cvsize.cpp index 39bcd51a..419e39cf 100644 --- a/ext/cvsize.cpp +++ b/ext/opencv/cvsize.cpp @@ -7,15 +7,15 @@ Copyright (C) 2005 Masakazu Yonekura ************************************************************/ -#include"cvsize.h" +#include "cvsize.h" /* * Document-class: OpenCV::CvSize * * This class means one size on X axis Y axis. - * X and Y takes the value of the Fixnum. + * X and Y takes the value of the Integer. * * C structure is here, very simple. - * typdef struct CvSize{ + * typdef struct CvSize { * int width; * int height; * } @@ -31,31 +31,6 @@ rb_class() return rb_klass; } -void -define_ruby_class() -{ - if(rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - rb_klass = rb_define_class_under(opencv, "CvSize", rb_cObject); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_singleton_method(rb_klass, "compatible?", RUBY_METHOD_FUNC(rb_compatible_q), 1); - rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); - rb_define_method(rb_klass, "width", RUBY_METHOD_FUNC(rb_width), 0); - rb_define_method(rb_klass, "width=", RUBY_METHOD_FUNC(rb_set_width), 1); - rb_define_method(rb_klass, "height", RUBY_METHOD_FUNC(rb_height), 0); - rb_define_method(rb_klass, "height=", RUBY_METHOD_FUNC(rb_set_height), 1); - - rb_define_method(rb_klass, "to_s", RUBY_METHOD_FUNC(rb_to_s), 0); - rb_define_method(rb_klass, "to_ary", RUBY_METHOD_FUNC(rb_to_ary), 0); -} - /* * call-seq: * compatible?(obj) @@ -103,28 +78,25 @@ rb_allocate(VALUE klass) VALUE rb_initialize(int argc, VALUE *argv, VALUE self) { - VALUE obj, x, y; + CvSize *self_ptr = CVSIZE(self); switch (argc) { case 0: break; - case 1: - obj = argv[0]; - if(rb_compatible_q(rb_klass, obj)) { - CVSIZE(self)->width = NUM2INT(rb_funcall(rb_funcall(obj, rb_intern("width"), 0), rb_intern("to_i"), 0)); - CVSIZE(self)->height = NUM2INT(rb_funcall(rb_funcall(obj, rb_intern("height"), 0), rb_intern("to_i"), 0)); - }else{ - rb_raise(rb_eArgError, "object is not compatible %s.", rb_class2name(rb_klass)); - } + case 1: { + CvSize size = VALUE_TO_CVSIZE(argv[0]); + self_ptr->width = size.width; + self_ptr->height = size.height; break; + } case 2: - x = argv[0], y = argv[1]; - CVSIZE(self)->width = NUM2INT(x); - CVSIZE(self)->height = NUM2INT(y); + self_ptr->width = NUM2INT(argv[0]); + self_ptr->height = NUM2INT(argv[1]); break; default: rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc); + break; } - return Qnil; + return self; } /* @@ -133,7 +105,7 @@ rb_initialize(int argc, VALUE *argv, VALUE self) VALUE rb_width(VALUE self) { - return INT2FIX(CVSIZE(self)->width); + return INT2NUM(CVSIZE(self)->width); } /* @@ -156,7 +128,7 @@ rb_set_width(VALUE self, VALUE x) VALUE rb_height(VALUE self) { - return INT2FIX(CVSIZE(self)->height); + return INT2NUM(CVSIZE(self)->height); } /* @@ -219,5 +191,37 @@ new_object(CvSize size) return object; } +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + + rb_klass = rb_define_class_under(opencv, "CvSize", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_singleton_method(rb_klass, "compatible?", RUBY_METHOD_FUNC(rb_compatible_q), 1); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "width", RUBY_METHOD_FUNC(rb_width), 0); + rb_define_method(rb_klass, "width=", RUBY_METHOD_FUNC(rb_set_width), 1); + rb_define_method(rb_klass, "height", RUBY_METHOD_FUNC(rb_height), 0); + rb_define_method(rb_klass, "height=", RUBY_METHOD_FUNC(rb_set_height), 1); + + rb_define_method(rb_klass, "to_s", RUBY_METHOD_FUNC(rb_to_s), 0); + rb_define_method(rb_klass, "to_ary", RUBY_METHOD_FUNC(rb_to_ary), 0); + rb_define_alias(rb_klass, "to_a", "to_ary"); +} + __NAMESPACE_END_CVSIZE __NAMESPACE_END_OPENCV + diff --git a/ext/cvsize.h b/ext/opencv/cvsize.h similarity index 81% rename from ext/cvsize.h rename to ext/opencv/cvsize.h index 8a75afc3..a0b0c767 100644 --- a/ext/cvsize.h +++ b/ext/opencv/cvsize.h @@ -10,9 +10,9 @@ #ifndef RUBY_OPENCV_CVSIZE_H #define RUBY_OPENCV_CVSIZE_H -#include"opencv.h" +#include "opencv.h" -#define __NAMESPACE_BEGIN_CVSIZE namespace cCvSize{ +#define __NAMESPACE_BEGIN_CVSIZE namespace cCvSize { #define __NAMESPACE_END_CVSIZE } __NAMESPACE_BEGIN_OPENCV @@ -20,7 +20,7 @@ __NAMESPACE_BEGIN_CVSIZE VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_compatible_q(VALUE klass, VALUE object); @@ -50,12 +50,14 @@ CVSIZE(VALUE object) inline CvSize VALUE_TO_CVSIZE(VALUE object) { - if(cCvSize::rb_compatible_q(cCvSize::rb_class(), object)){ + if (cCvSize::rb_compatible_q(cCvSize::rb_class(), object)) { return cvSize(NUM2INT(rb_funcall(object, rb_intern("width"), 0)), NUM2INT(rb_funcall(object, rb_intern("height"), 0))); - }else{ - rb_raise(rb_eTypeError, "require %s or compatible object.", rb_class2name(cCvSize::rb_class())); } + else { + raise_compatible_typeerror(object, cCvSize::rb_class()); + } + throw "Should never reach here"; } __NAMESPACE_END_OPENCV diff --git a/ext/cvsize2d32f.cpp b/ext/opencv/cvsize2d32f.cpp similarity index 73% rename from ext/cvsize2d32f.cpp rename to ext/opencv/cvsize2d32f.cpp index 85a82c98..5b7a3275 100644 --- a/ext/cvsize2d32f.cpp +++ b/ext/opencv/cvsize2d32f.cpp @@ -15,10 +15,10 @@ * X and Y takes the value of the Float. * * C structure is here, very simple. - * typdef struct CvSize2D32f{ + * typdef struct CvSize2D32f { * float width; * float height; - * }CvSize2D32f; + * } CvSize2D32f; */ __NAMESPACE_BEGIN_OPENCV __NAMESPACE_BEGIN_CVSIZE2D32F @@ -31,28 +31,6 @@ rb_class() return rb_klass; } -void -define_ruby_class() -{ - if(rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - rb_klass = rb_define_class_under(opencv, "CvSize2D32f", rb_cObject); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_singleton_method(rb_klass, "compatible?", RUBY_METHOD_FUNC(rb_compatible_q), 1); - rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); - rb_define_method(rb_klass, "width", RUBY_METHOD_FUNC(rb_width), 0); - rb_define_method(rb_klass, "width=", RUBY_METHOD_FUNC(rb_set_width), 1); - rb_define_method(rb_klass, "height", RUBY_METHOD_FUNC(rb_height), 0); - rb_define_method(rb_klass, "height=", RUBY_METHOD_FUNC(rb_set_height), 1); -} - /* * call-seq: * compatible?(obj) @@ -100,23 +78,19 @@ rb_allocate(VALUE klass) VALUE rb_initialize(int argc, VALUE *argv, VALUE self) { - VALUE obj, x, y; + CvSize2D32f *self_ptr = CVSIZE2D32F(self); switch(argc){ case 0: break; - case 1: - obj = argv[0]; - if(rb_compatible_q(rb_klass, obj)){ - CVSIZE2D32F(self)->width = NUM2DBL(rb_funcall(rb_funcall(obj, rb_intern("width"), 0), rb_intern("to_f"), 0)); - CVSIZE2D32F(self)->height = NUM2DBL(rb_funcall(rb_funcall(obj, rb_intern("height"), 0), rb_intern("to_f"), 0)); - }else{ - rb_raise(rb_eArgError, "object is not compatible %s.", rb_class2name(rb_klass)); - } + case 1: { + CvSize2D32f size = VALUE_TO_CVSIZE2D32F(argv[0]); + self_ptr->width = size.width; + self_ptr->height = size.height; break; + } case 2: - x = argv[0], y = argv[1]; - CVSIZE2D32F(self)->width = NUM2DBL(x); - CVSIZE2D32F(self)->height = NUM2DBL(y); + self_ptr->width = NUM2DBL(argv[0]); + self_ptr->height = NUM2DBL(argv[1]); break; default: rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc); @@ -168,6 +142,36 @@ rb_set_height(VALUE self, VALUE y) return self; } +/* + * call-seq: + * to_s -> "" + * + * Return width and height by String. + */ +VALUE +rb_to_s(VALUE self) +{ + const int i = 4; + VALUE str[i]; + str[0] = rb_str_new2("<%s:%gx%g>"); + str[1] = rb_str_new2(rb_class2name(CLASS_OF(self))); + str[2] = rb_width(self); + str[3] = rb_height(self); + return rb_f_sprintf(i, str); +} + +/* + * call-seq: + * to_ary -> [width, height] + * + * Return width and height by Array. + */ +VALUE +rb_to_ary(VALUE self) +{ + return rb_ary_new3(2, rb_width(self), rb_height(self)); +} + VALUE new_object(CvSize2D32f size) { @@ -176,5 +180,36 @@ new_object(CvSize2D32f size) return object; } +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + + rb_klass = rb_define_class_under(opencv, "CvSize2D32f", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_singleton_method(rb_klass, "compatible?", RUBY_METHOD_FUNC(rb_compatible_q), 1); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "width", RUBY_METHOD_FUNC(rb_width), 0); + rb_define_method(rb_klass, "width=", RUBY_METHOD_FUNC(rb_set_width), 1); + rb_define_method(rb_klass, "height", RUBY_METHOD_FUNC(rb_height), 0); + rb_define_method(rb_klass, "height=", RUBY_METHOD_FUNC(rb_set_height), 1); + rb_define_method(rb_klass, "to_s", RUBY_METHOD_FUNC(rb_to_s), 0); + rb_define_method(rb_klass, "to_ary", RUBY_METHOD_FUNC(rb_to_ary), 0); + rb_define_alias(rb_klass, "to_a", "to_ary"); +} + __NAMESPACE_END_CVSIZE2D32F __NAMESPACE_END_OPENCV + diff --git a/ext/cvsize2d32f.h b/ext/opencv/cvsize2d32f.h similarity index 78% rename from ext/cvsize2d32f.h rename to ext/opencv/cvsize2d32f.h index ca038b45..d025e89f 100644 --- a/ext/cvsize2d32f.h +++ b/ext/opencv/cvsize2d32f.h @@ -12,7 +12,7 @@ #include "opencv.h" -#define __NAMESPACE_BEGIN_CVSIZE2D32F namespace cCvSize2D32f{ +#define __NAMESPACE_BEGIN_CVSIZE2D32F namespace cCvSize2D32f { #define __NAMESPACE_END_CVSIZE2D32F } __NAMESPACE_BEGIN_OPENCV @@ -20,7 +20,7 @@ __NAMESPACE_BEGIN_CVSIZE2D32F VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_compatible_q(VALUE klass, VALUE object); @@ -31,6 +31,9 @@ VALUE rb_set_width(VALUE self, VALUE width); VALUE rb_height(VALUE self); VALUE rb_set_height(VALUE self, VALUE height); +VALUE rb_to_s(VALUE self); +VALUE rb_to_ary(VALUE self); + VALUE new_object(CvSize2D32f size); __NAMESPACE_END_CVSIZE2D32F @@ -46,12 +49,14 @@ CVSIZE2D32F(VALUE object) inline CvSize2D32f VALUE_TO_CVSIZE2D32F(VALUE object) { - if(cCvSize2D32f::rb_compatible_q(cCvSize2D32f::rb_class(), object)){ + if (cCvSize2D32f::rb_compatible_q(cCvSize2D32f::rb_class(), object)) { return cvSize2D32f(NUM2DBL(rb_funcall(object, rb_intern("width"), 0)), NUM2DBL(rb_funcall(object, rb_intern("height"), 0))); - }else{ - rb_raise(rb_eTypeError, "require %s or compatible object.", rb_class2name(cCvSize2D32f::rb_class())); } + else { + raise_compatible_typeerror(object, cCvSize2D32f::rb_class()); + } + throw "Should never reach here"; } __NAMESPACE_END_OPENCV diff --git a/ext/opencv/cvslice.cpp b/ext/opencv/cvslice.cpp new file mode 100644 index 00000000..29e85b8f --- /dev/null +++ b/ext/opencv/cvslice.cpp @@ -0,0 +1,126 @@ +/************************************************************ + + cvslice.cpp - + + $Author: lsxi $ + + Copyright (C) 2005-2006 Masakazu Yonekura + +************************************************************/ +#include "cvslice.h" +/* + * Document-class: OpenCV::CvSlice + * + * C structure is here, very simple. + * typdef struct CvSlice { + * int start_index; + * int end_index; + * } CvSlice; + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVSLICE + +VALUE rb_klass; + +VALUE +rb_class() +{ + return rb_klass; +} + +VALUE +rb_allocate(VALUE klass) +{ + CvSlice *ptr; + return Data_Make_Struct(klass, CvSlice, 0, -1, ptr); +} + +/* + * call-seq: + * new(start, end) + * + * Create new slice object. + */ +VALUE +rb_initialize(VALUE self, VALUE start, VALUE end) +{ + CvSlice *self_ptr = CVSLICE(self); + self_ptr->start_index = NUM2INT(start); + self_ptr->end_index = NUM2INT(end); + return self; +} + +/* + * call-seq: + * start_index + * + */ +VALUE +rb_start_index_aref(VALUE self) +{ + return INT2NUM(CVSLICE(self)->start_index); +} + +/* + * call-seq: + * end_index + * + */ +VALUE +rb_end_index_aref(VALUE self) +{ + return INT2NUM(CVSLICE(self)->end_index); +} + +/* + * call-seq: + * start_index = index + * + */ +VALUE +rb_start_index_aset(VALUE self, VALUE index) +{ + CVSLICE(self)->start_index = NUM2INT(index); + return self; +} + +/* + * call-seq: + * end_index = index + * + */ +VALUE +rb_end_index_aset(VALUE self, VALUE index) +{ + CVSLICE(self)->end_index = NUM2INT(index); + return self; +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + rb_klass = rb_define_class_under(opencv, "CvSlice", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), 2); + rb_define_method(rb_klass, "start_index", RUBY_METHOD_FUNC(rb_start_index_aref), 0); + rb_define_method(rb_klass, "end_index", RUBY_METHOD_FUNC(rb_end_index_aref), 0); + rb_define_method(rb_klass, "start_index=", RUBY_METHOD_FUNC(rb_start_index_aset), 1); + rb_define_method(rb_klass, "end_index=", RUBY_METHOD_FUNC(rb_end_index_aset), 1); +} + +__NAMESPACE_END_CVSLICE +__NAMESPACE_END_OPENCV + diff --git a/ext/cvslice.h b/ext/opencv/cvslice.h similarity index 64% rename from ext/cvslice.h rename to ext/opencv/cvslice.h index fd7a64b6..f4851ece 100644 --- a/ext/cvslice.h +++ b/ext/opencv/cvslice.h @@ -12,7 +12,7 @@ #include "opencv.h" -#define __NAMESPACE_BEGIN_CVSLICE namespace cCvSlice{ +#define __NAMESPACE_BEGIN_CVSLICE namespace cCvSlice { #define __NAMESPACE_END_CVSLICE } __NAMESPACE_BEGIN_OPENCV @@ -20,12 +20,14 @@ __NAMESPACE_BEGIN_CVSLICE VALUE rb_class(); -void define_ruby_class(); - -VALUE rb_compatible_q(VALUE klass, VALUE object); +void init_ruby_class(); VALUE rb_allocate(VALUE klass); VALUE rb_initialize(VALUE self, VALUE start, VALUE end); +VALUE rb_start_index_aref(VALUE self); +VALUE rb_end_index_aref(VALUE self); +VALUE rb_start_index_aset(VALUE self, VALUE index); +VALUE rb_end_index_aset(VALUE self, VALUE index); __NAMESPACE_END_CVSLICE @@ -40,12 +42,18 @@ CVSLICE(VALUE object) inline CvSlice VALUE_TO_CVSLICE(VALUE object) { - if(cCvSlice::rb_compatible_q(cCvSlice::rb_class(), object)){ + if (rb_obj_is_kind_of(object, cCvSlice::rb_class())) { + CvSlice* ptr = CVSLICE(object); + return *ptr; + } + else if (rb_obj_is_kind_of(object, rb_cRange)) { return cvSlice(NUM2INT(rb_funcall(object, rb_intern("begin"), 0)), rb_funcall(object, rb_intern("exclude_end?"), 0) ? NUM2INT(rb_funcall(object, rb_intern("end"), 0)) : NUM2INT(rb_funcall(object, rb_intern("end"), 0)) - 1); - }else{ - rb_raise(rb_eTypeError, "require %s or compatible object.", rb_class2name(cCvSlice::rb_class())); } + else { + raise_compatible_typeerror(object, cCvSlice::rb_class()); + } + throw "Should never reach here"; } __NAMESPACE_END_OPENCV diff --git a/ext/opencv/cvsurfparams.cpp b/ext/opencv/cvsurfparams.cpp new file mode 100644 index 00000000..31017896 --- /dev/null +++ b/ext/opencv/cvsurfparams.cpp @@ -0,0 +1,208 @@ +/************************************************************ + + cvsurfparams.cpp - + + $Author: ser1zw $ + + Copyright (C) 2011 ser1zw + +************************************************************/ +#include "cvsurfparams.h" +/* + * Document-class: OpenCV::CvSURFParams + * + * C structure is here. + * typedef struct CvSURFParams { + * int extended; + * double hessianThreshold; + * int nOctaves; + * int nOctaveLayers; + * } CvSURFParams; + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVSURFPARAMS + +VALUE rb_klass; + +VALUE +rb_class() +{ + return rb_klass; +} + +VALUE +rb_allocate(VALUE klass) +{ + CvSURFParams *ptr; + return Data_Make_Struct(klass, CvSURFParams, 0, -1, ptr); +} + +/* + * Create a CvSURFParams + * + * @overload CvSURFParams.new(hessian_threshold, extended = false, n_octaves = 3, n_octave_layers = 4) + * @param hessian_threshold [Number] + * @param extended [Boolean] If true, exteneded descriptors (128 elements each), + * otherwise basic descriptors (64 elements each) + * @param n_octaves [Integer] Number of octaves to be used for extraction + * @param n_octave_layers [Integer] Number of layers within each octave + */ +VALUE +rb_initialize(int argc, VALUE *argv, VALUE self) +{ + CvSURFParams *self_ptr = CVSURFPARAMS(self); + VALUE h_thresh, ext, noct, noctl; + rb_scan_args(argc, argv, "13", &h_thresh, &ext, &noct, &noctl); + + self_ptr->hessianThreshold = NUM2DBL(h_thresh); + self_ptr->extended = NIL_P(ext) ? 0 : BOOL2INT(ext); + self_ptr->nOctaves = NIL_P(noct) ? 3 : NUM2INT(noct); + self_ptr->nOctaveLayers = NIL_P(noctl) ? 4 : NUM2INT(noctl); + + return self; +} + +/* + * call-seq: + * hessian_threshold -> number + * Return threshold of hessian + */ +VALUE +rb_get_hessian_threshold(VALUE self) +{ + return DBL2NUM(CVSURFPARAMS(self)->hessianThreshold); +} + +/* + * call-seq: + * hessian_threshold = value + * + * Set threshold of hessian to value + */ +VALUE +rb_set_hessian_threshold(VALUE self, VALUE value) +{ + CVSURFPARAMS(self)->hessianThreshold = NUM2DBL(value); + return self; +} + +/* + * call-seq: + * extended -> bool + * Return the type of descripters + * false: basic descriptors (64 elements each) + * true : exteneded descriptors (128 elements each) + */ +VALUE +rb_get_extended(VALUE self) +{ + return INT2BOOL(CVSURFPARAMS(self)->extended); +} + +/* + * call-seq: + * extended = value + * Set the type of descripters + * false: basic descriptors (64 elements each) + * true : exteneded descriptors (128 elements each) + */ +VALUE +rb_set_extended(VALUE self, VALUE value) +{ + CVSURFPARAMS(self)->extended = BOOL2INT(value); + return self; +} + +/* + * call-seq: + * n_octaves -> fixnum + * Return the number of octaves to be used for extraction + */ +VALUE +rb_get_n_octaves(VALUE self) +{ + return INT2NUM(CVSURFPARAMS(self)->nOctaves); +} + +/* + * call-seq: + * n_octaves = value + * Set the number of octaves to be used for extraction + */ +VALUE +rb_set_n_octaves(VALUE self, VALUE value) +{ + CVSURFPARAMS(self)->nOctaves = NUM2INT(value); + return self; +} + +/* + * call-seq: + * n_octave_layers -> fixnum + * Return the number of layers within each octave + */ +VALUE +rb_get_n_octave_layers(VALUE self) +{ + return INT2NUM(CVSURFPARAMS(self)->nOctaveLayers); +} + +/* + * call-seq: + * n_octave_layers = value + * Set the number of layers within each octave + */ +VALUE +rb_set_n_octave_layers(VALUE self, VALUE value) +{ + CVSURFPARAMS(self)->nOctaveLayers = NUM2INT(value); + return self; +} + +VALUE +new_object() +{ + return rb_allocate(rb_klass); +} + +VALUE +new_object(CvSURFParams* cvsurfparams) +{ + VALUE object = rb_allocate(rb_klass); + CvSURFParams *ptr = CVSURFPARAMS(object); + ptr = cvsurfparams; + return object; +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + rb_klass = rb_define_class_under(opencv, "CvSURFParams", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "hessian_threshold", RUBY_METHOD_FUNC(rb_get_hessian_threshold), 0); + rb_define_method(rb_klass, "hessian_threshold=", RUBY_METHOD_FUNC(rb_set_hessian_threshold), 1); + rb_define_method(rb_klass, "extended", RUBY_METHOD_FUNC(rb_get_extended), 0); + rb_define_method(rb_klass, "extended=", RUBY_METHOD_FUNC(rb_set_extended), 1); + rb_define_method(rb_klass, "n_octaves", RUBY_METHOD_FUNC(rb_get_n_octaves), 0); + rb_define_method(rb_klass, "n_octaves=", RUBY_METHOD_FUNC(rb_set_n_octaves), 1); + rb_define_method(rb_klass, "n_octave_layers", RUBY_METHOD_FUNC(rb_get_n_octave_layers), 0); + rb_define_method(rb_klass, "n_octave_layers=", RUBY_METHOD_FUNC(rb_set_n_octave_layers), 1); +} + +__NAMESPACE_END_CVSURFPARAMS +__NAMESPACE_END_OPENCV + diff --git a/ext/opencv/cvsurfparams.h b/ext/opencv/cvsurfparams.h new file mode 100644 index 00000000..ae4d0080 --- /dev/null +++ b/ext/opencv/cvsurfparams.h @@ -0,0 +1,58 @@ +/************************************************************ + + cvsurfparams.h - + + $Author: ser1zw $ + + Copyright (C) 2011 ser1zw + +************************************************************/ +#ifndef RUBY_OPENCV_CVSURFPARAMS_H +#define RUBY_OPENCV_CVSURFPARAMS_H + +#include "opencv.h" + +#define __NAMESPACE_BEGIN_CVSURFPARAMS namespace cCvSURFParams { +#define __NAMESPACE_END_CVSURFPARAMS } + +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVSURFPARAMS + +VALUE rb_class(); + +void init_ruby_class(); + +VALUE rb_allocate(VALUE klass); +VALUE rb_initialize(int argc, VALUE *argv, VALUE self); +VALUE rb_get_hessian_threshold(VALUE self); +VALUE rb_set_hessian_threshold(VALUE self, VALUE value); +VALUE rb_get_extended(VALUE self); +VALUE rb_set_extended(VALUE self, VALUE value); +VALUE rb_get_n_octaves(VALUE self); +VALUE rb_set_n_octaves(VALUE self, VALUE value); +VALUE rb_get_n_octave_layers(VALUE self); +VALUE rb_set_n_octave_layers(VALUE self, VALUE value); + +VALUE new_object(CvSURFPoint *cvsurfparams); + +__NAMESPACE_END_CVSURFPARAMS + +inline CvSURFParams* +CVSURFPARAMS(VALUE object) +{ + CvSURFParams* ptr; + Data_Get_Struct(object, CvSURFParams, ptr); + return ptr; +} + +inline CvSURFParams* +CVSURFPARAMS_WITH_CHECK(VALUE object) +{ + if (!rb_obj_is_kind_of(object, cCvSURFParams::rb_class())) + raise_typeerror(object, cCvSURFParams::rb_class()); + return CVSURFPARAMS(object); +} + +__NAMESPACE_END_OPENCV + +#endif // RUBY_OPENCV_CVSURFPARAMS_H diff --git a/ext/opencv/cvsurfpoint.cpp b/ext/opencv/cvsurfpoint.cpp new file mode 100644 index 00000000..4564270a --- /dev/null +++ b/ext/opencv/cvsurfpoint.cpp @@ -0,0 +1,246 @@ +/************************************************************ + + cvsurfpoint.cpp - + + $Author: ser1zw $ + + Copyright (C) 2011 ser1zw + +************************************************************/ +#include "cvsurfpoint.h" +/* + * Document-class: OpenCV::CvSURFPoint + * + * C structure is here. + * typedef struct CvSURFPoint { + * CvPoint2D32f pt; // position of the feature within the image + * int laplacian; // -1, 0 or +1. sign of the laplacian at the point. + * // can be used to speedup feature comparison + * // (normally features with laplacians of different + * // signs can not match) + * int size; // size of the feature + * float dir; // orientation of the feature: 0..360 degrees + * float hessian; // value of the hessian (can be used to + * // approximately estimate the feature strengths) + * } CvSURFPoint; + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVSURFPOINT + +VALUE rb_klass; + +VALUE +rb_class() +{ + return rb_klass; +} + +VALUE +rb_allocate(VALUE klass) +{ + CvSURFPoint *ptr; + return Data_Make_Struct(klass, CvSURFPoint, 0, -1, ptr); +} + +/* + * Create a CvSURFPoint + * + * @overload new(pt, laplacian, size, dir, hessian) + * @param pt [CvPoint2D32f] Position of the feature within the image + * @param laplacian [Integer] -1, 0 or +1. sign of the laplacian at the point. + * Can be used to speedup feature comparison + * (normally features with laplacians of different signs can not match) + * @param size [Integer] Size of the feature + * @param dir [Number] Orientation of the feature: 0..360 degrees + * @param hessian [Number] Value of the hessian (can be used to + * approximately estimate the feature strengths) + * @return [CvSURFPoint] self + */ +VALUE +rb_initialize(VALUE self, VALUE pt, VALUE laplacian, VALUE size, VALUE dir, VALUE hessian) +{ + CvSURFPoint *self_ptr = CVSURFPOINT(self); + self_ptr->pt = VALUE_TO_CVPOINT2D32F(pt); + self_ptr->laplacian = NUM2INT(laplacian); + self_ptr->size = NUM2INT(size); + self_ptr->dir = (float)NUM2DBL(dir); + self_ptr->hessian = (float)NUM2DBL(hessian); + + return self; +} + +/* + * Return position of the feature as CvPoint2D32f. + * + * @overload pt + * @return [CvPoint2D32f] Position of the feature. + */ +VALUE +rb_get_pt(VALUE self) +{ + return REFER_OBJECT(cCvPoint2D32f::rb_class(), &CVSURFPOINT(self)->pt, self); +} + +/* + * Set position of the feature. + * + * @overload pt=(value) + * @param value [CvPoint2D32f] Valuet to set. + */ +VALUE +rb_set_pt(VALUE self, VALUE value) +{ + CVSURFPOINT(self)->pt = VALUE_TO_CVPOINT2D32F(value); + return self; +} + +/* + * Return sign of the laplacian at the point (-1, 0 or +1) + * + * @overload laplacian + * @return [Integer] Sign of the laplacian at the point. + */ +VALUE +rb_get_laplacian(VALUE self) +{ + return INT2NUM(CVSURFPOINT(self)->laplacian); +} + +/* + * Set sign of the laplacian at the point + * + * @overload laplacian=(value) + * @param value [Integer] Value to set. + */ +VALUE +rb_set_laplacian(VALUE self, VALUE value) +{ + int val = NUM2INT(value); + CVSURFPOINT(self)->laplacian = (val > 0) ? 1 : (val < 0) ? -1 : 0; + return self; +} + +/* + * Returns size of feature. + * + * @overload size + * @return [Integer] Size of feature. + */ +VALUE +rb_get_size(VALUE self) +{ + return INT2NUM(CVSURFPOINT(self)->size); +} + +/* + * Return size of feature + * + * @overload size=(value) + * @param [Integer] Value to set. + */ +VALUE +rb_set_size(VALUE self, VALUE value) +{ + CVSURFPOINT(self)->size = NUM2INT(value); + return self; +} + +/* + * Return orientation of the feature: 0..360 degrees + * + * @overload dir + * @return [Number] Orientation of the feature. + */ +VALUE +rb_get_dir(VALUE self) +{ + return DBL2NUM((double)(CVSURFPOINT(self)->dir)); +} + +/* + * Set orientation of the feature: 0..360 degrees. + * + * @overload dir=(value) + * @param [Number] Value to set. + */ +VALUE +rb_set_dir(VALUE self, VALUE value) +{ + CVSURFPOINT(self)->dir = (float)NUM2DBL(value); + return self; +} + +/* + * Return value of the hessian + * + * @overload hessian + * @return [Number] Hessian + */ +VALUE +rb_get_hessian(VALUE self) +{ + return DBL2NUM((double)(CVSURFPOINT(self)->hessian)); +} + +/* + * Set value of the hessian + * + * @overload hessian=(value) + * @param [Number] Value to set. + */ +VALUE +rb_set_hessian(VALUE self, VALUE value) +{ + CVSURFPOINT(self)->hessian = (float)NUM2DBL(value); + return self; +} + +VALUE +new_object() +{ + return rb_allocate(rb_klass); +} + +VALUE +new_object(CvSURFPoint* cvsurfpoint) +{ + VALUE object = rb_allocate(rb_klass); + CvSURFPoint *ptr = CVSURFPOINT(object); + ptr = cvsurfpoint; + return object; +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + rb_klass = rb_define_class_under(opencv, "CvSURFPoint", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), 5); + rb_define_method(rb_klass, "pt", RUBY_METHOD_FUNC(rb_get_pt), 0); + rb_define_method(rb_klass, "pt=", RUBY_METHOD_FUNC(rb_set_pt), 1); + rb_define_method(rb_klass, "laplacian", RUBY_METHOD_FUNC(rb_get_laplacian), 0); + rb_define_method(rb_klass, "laplacian=", RUBY_METHOD_FUNC(rb_set_laplacian), 1); + rb_define_method(rb_klass, "size", RUBY_METHOD_FUNC(rb_get_size), 0); + rb_define_method(rb_klass, "size=", RUBY_METHOD_FUNC(rb_set_size), 1); + rb_define_method(rb_klass, "dir", RUBY_METHOD_FUNC(rb_get_dir), 0); + rb_define_method(rb_klass, "dir=", RUBY_METHOD_FUNC(rb_set_dir), 1); + rb_define_method(rb_klass, "hessian", RUBY_METHOD_FUNC(rb_get_hessian), 0); + rb_define_method(rb_klass, "hessian=", RUBY_METHOD_FUNC(rb_set_hessian), 1); +} + +__NAMESPACE_END_CVSURFPOINT +__NAMESPACE_END_OPENCV + diff --git a/ext/opencv/cvsurfpoint.h b/ext/opencv/cvsurfpoint.h new file mode 100644 index 00000000..b652ae32 --- /dev/null +++ b/ext/opencv/cvsurfpoint.h @@ -0,0 +1,52 @@ +/************************************************************ + + cvsurfpoint.h - + + $Author: ser1zw $ + + Copyright (C) 2011 ser1zw + +************************************************************/ +#ifndef RUBY_OPENCV_CVSURFPOINT_H +#define RUBY_OPENCV_CVSURFPOINT_H + +#include "opencv.h" + +#define __NAMESPACE_BEGIN_CVSURFPOINT namespace cCvSURFPoint { +#define __NAMESPACE_END_CVSURFPOINT } + +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_CVSURFPOINT + +VALUE rb_class(); + +void init_ruby_class(); + +VALUE rb_allocate(VALUE klass); +VALUE rb_initialize(VALUE self, VALUE pt, VALUE laplacian, VALUE size, VALUE dir, VALUE hessian); +VALUE rb_get_pt(VALUE self); +VALUE rb_set_pt(VALUE self, VALUE value); +VALUE rb_get_laplacian(VALUE self); +VALUE rb_set_laplacian(VALUE self, VALUE value); +VALUE rb_get_size(VALUE self); +VALUE rb_set_size(VALUE self, VALUE value); +VALUE rb_get_dir(VALUE self); +VALUE rb_set_dir(VALUE self, VALUE value); +VALUE rb_get_hessian(VALUE self); +VALUE rb_set_hessian(VALUE self, VALUE value); + +VALUE new_object(CvSURFPoint *cvsurfpoint); + +__NAMESPACE_END_CVSURFPOINT + +inline CvSURFPoint* +CVSURFPOINT(VALUE object) +{ + CvSURFPoint* ptr; + Data_Get_Struct(object, CvSURFPoint, ptr); + return ptr; +} + +__NAMESPACE_END_OPENCV + +#endif // RUBY_OPENCV_CVSURFPOINT_H diff --git a/ext/cvtermcriteria.cpp b/ext/opencv/cvtermcriteria.cpp similarity index 85% rename from ext/cvtermcriteria.cpp rename to ext/opencv/cvtermcriteria.cpp index af6ffc81..ef2e02a3 100644 --- a/ext/cvtermcriteria.cpp +++ b/ext/opencv/cvtermcriteria.cpp @@ -7,7 +7,7 @@ Copyright (C) 2005-2006 Masakazu Yonekura ************************************************************/ -#include"cvtermcriteria.h" +#include "cvtermcriteria.h" /* * Document-class: OpenCV::CvTermCriteria * @@ -29,32 +29,6 @@ rb_class() return rb_klass; } -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - rb_klass = rb_define_class_under(opencv, "CvTermCriteria", rb_cObject); - /* CvTermCriteria: class */ - rb_define_const(opencv, "CvTerm", rb_klass); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); - rb_define_method(rb_klass, "max", RUBY_METHOD_FUNC(rb_max), 0); - rb_define_method(rb_klass, "max=", RUBY_METHOD_FUNC(rb_set_max), 1); - rb_define_method(rb_klass, "eps", RUBY_METHOD_FUNC(rb_eps), 0); - rb_define_method(rb_klass, "eps=", RUBY_METHOD_FUNC(rb_set_eps), 1); - rb_define_alias(rb_klass, "epsilon", "eps"); - rb_define_alias(rb_klass, "epsilon=", "eps="); - rb_define_method(rb_klass, "to_ary", RUBY_METHOD_FUNC(rb_to_ary), 0); -} - VALUE rb_allocate(VALUE klass) { @@ -76,12 +50,31 @@ rb_initialize(int argc, VALUE *argv, VALUE self) VALUE max, eps; rb_scan_args(argc, argv, "02", &max, &eps); int type = 0; - if (!NIL_P(max)) {type |= CV_TERMCRIT_ITER;} - if (!NIL_P(eps)) {type |= CV_TERMCRIT_EPS;} - *CVTERMCRITERIA(self) = cvTermCriteria(type, IF_INT(max, 0), IF_DBL(eps, 0.0)); + if (!NIL_P(max)) + type |= CV_TERMCRIT_ITER; + if (!NIL_P(eps)) + type |= CV_TERMCRIT_EPS; + try { + *CVTERMCRITERIA(self) = cvTermCriteria(type, IF_INT(max, 0), IF_DBL(eps, 0.0)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } return self; } +/* + * call-seq: + * type -> int + * + * Return a combination of CV_TERMCRIT_ITER and CV_TERMCRIT_EPS + */ +VALUE +rb_type(VALUE self) +{ + return INT2NUM(CVTERMCRITERIA(self)->type); +} + /* * call-seq: * max -> int or nil @@ -113,7 +106,8 @@ rb_set_max(VALUE self, VALUE max_value) if (max > 0) { ptr->type |= CV_TERMCRIT_ITER; ptr->max_iter = max; - } else { + } + else { ptr->type ^= CV_TERMCRIT_ITER; ptr->max_iter = 0; } @@ -130,7 +124,7 @@ VALUE rb_eps(VALUE self) { CvTermCriteria *ptr = CVTERMCRITERIA(self); - if(ptr->type & CV_TERMCRIT_EPS) + if (ptr->type & CV_TERMCRIT_EPS) return rb_float_new(ptr->epsilon); else return Qnil; @@ -152,25 +146,14 @@ rb_set_eps(VALUE self, VALUE eps_value) if (eps > 0) { ptr->type = ptr->type | CV_TERMCRIT_EPS; ptr->epsilon = eps; - } else { + } + else { ptr->type = ptr->type ^ CV_TERMCRIT_EPS; ptr->epsilon = 0; } return self; } -VALUE -rb_to_ary(VALUE self) -{ - CvTermCriteria *ptr = CVTERMCRITERIA(self); - VALUE ary = rb_ary_new(); - if (ptr->type & CV_TERMCRIT_ITER) - rb_ary_push(ary, INT2FIX(ptr->max_iter)); - if (ptr->type & CV_TERMCRIT_EPS) - rb_ary_push(ary, rb_float_new(ptr->epsilon)); - return ary; -} - VALUE new_object(CvTermCriteria criteria) { @@ -179,5 +162,37 @@ new_object(CvTermCriteria criteria) return object; } +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + + rb_klass = rb_define_class_under(opencv, "CvTermCriteria", rb_cObject); + /* CvTermCriteria: class */ + rb_define_const(opencv, "CvTerm", rb_klass); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "type", RUBY_METHOD_FUNC(rb_type), 0); + rb_define_method(rb_klass, "max", RUBY_METHOD_FUNC(rb_max), 0); + rb_define_method(rb_klass, "max=", RUBY_METHOD_FUNC(rb_set_max), 1); + rb_define_method(rb_klass, "eps", RUBY_METHOD_FUNC(rb_eps), 0); + rb_define_method(rb_klass, "eps=", RUBY_METHOD_FUNC(rb_set_eps), 1); + rb_define_alias(rb_klass, "epsilon", "eps"); + rb_define_alias(rb_klass, "epsilon=", "eps="); +} + __NAMESPACE_END_CVTERMCRITERIA __NAMESPACE_END_OPENCV + diff --git a/ext/cvtermcriteria.h b/ext/opencv/cvtermcriteria.h similarity index 88% rename from ext/cvtermcriteria.h rename to ext/opencv/cvtermcriteria.h index 16415ce1..b780168f 100644 --- a/ext/cvtermcriteria.h +++ b/ext/opencv/cvtermcriteria.h @@ -12,7 +12,7 @@ #include "opencv.h" -#define __NAMESPACE_BEGIN_CVTERMCRITERIA namespace cCvTermCriteria{ +#define __NAMESPACE_BEGIN_CVTERMCRITERIA namespace cCvTermCriteria { #define __NAMESPACE_END_CVTERMCRITERIA } __NAMESPACE_BEGIN_OPENCV @@ -20,16 +20,16 @@ __NAMESPACE_BEGIN_CVTERMCRITERIA VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_allocate(VALUE klass); VALUE rb_initialize(int argc, VALUE *argv, VALUE self); +VALUE rb_type(VALUE self); VALUE rb_max(VALUE self); VALUE rb_set_max(VALUE self, VALUE max_value); VALUE rb_eps(VALUE self); VALUE rb_set_eps(VALUE self, VALUE eps_value); -VALUE rb_to_ary(VALUE self); VALUE new_object(CvTermCriteria criteria); @@ -57,13 +57,13 @@ VALUE_TO_CVTERMCRITERIA(VALUE object) case T_FLOAT: return cvTermCriteria(CV_TERMCRIT_EPS, 0, NUM2DBL(object)); case T_ARRAY: - if (RARRAY(object)->len == 2) { - return cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, + if (RARRAY_LEN(object) == 2) { + return cvTermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, NUM2INT(rb_ary_entry(object, 0)), NUM2DBL(rb_ary_entry(object, 1))); } } - rb_raise(rb_eTypeError, ""); + rb_raise(rb_eTypeError, "Invalid type"); } __NAMESPACE_END_OPENCV diff --git a/ext/cvtwopoints.cpp b/ext/opencv/cvtwopoints.cpp similarity index 68% rename from ext/cvtwopoints.cpp rename to ext/opencv/cvtwopoints.cpp index f03fd686..089abe46 100644 --- a/ext/cvtwopoints.cpp +++ b/ext/opencv/cvtwopoints.cpp @@ -9,13 +9,13 @@ ************************************************************/ #include "cvtwopoints.h" /* - * Document-class: OpenCV::CvTwopoints + * Document-class: OpenCV::CvTwoPoints * * This class means one twopoints on X axis Y axis. - * X and Y takes the value of the Fixnum. see also CvTwopoints2D32F + * X and Y takes the value of the Integer. see also CvTwopoints2D32F * * C structure is here, very simple. - * typdef struct CvTwopoints{ + * typdef struct CvTwopoints { * int x; * int y; * } @@ -31,25 +31,6 @@ rb_class() return rb_klass; } -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - - rb_klass = rb_define_class_under(opencv, "CvTwoPoints", rb_cObject); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_method(rb_klass, "point1", RUBY_METHOD_FUNC(rb_point1), 0); - rb_define_method(rb_klass, "point2", RUBY_METHOD_FUNC(rb_point2), 0); - rb_define_method(rb_klass, "to_ary", RUBY_METHOD_FUNC(rb_to_ary), 0); -} - VALUE rb_allocate(VALUE klass) { @@ -57,13 +38,6 @@ rb_allocate(VALUE klass) return Data_Make_Struct(klass, CvTwoPoints, 0, -1, ptr); } -VALUE -rb_cvseqblock(VALUE self) -{ - return Qnil; -} - - /* * Return point 1. */ @@ -82,6 +56,29 @@ rb_point2(VALUE self) return cCvPoint::new_object(CVTWOPOINTS(self)->p2); } +/* + * call-seq: + * [index] + * + * Return value of index dimension. + */ +VALUE +rb_aref(VALUE self, VALUE index) +{ + switch (NUM2INT(index)) { + case 0: + return cCvPoint::new_object(CVTWOPOINTS(self)->p1); + break; + case 1: + return cCvPoint::new_object(CVTWOPOINTS(self)->p2); + break; + default: + rb_raise(rb_eIndexError, "index should be 0...2"); + break; + } + return Qnil; +} + /* * call-seq: * to_ary -> [self.point1, self.point2] @@ -94,5 +91,32 @@ rb_to_ary(VALUE self) return rb_ary_new3(2, rb_point1(self), rb_point2(self)); } +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + + rb_klass = rb_define_class_under(opencv, "CvTwoPoints", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_method(rb_klass, "point1", RUBY_METHOD_FUNC(rb_point1), 0); + rb_define_method(rb_klass, "point2", RUBY_METHOD_FUNC(rb_point2), 0); + rb_define_method(rb_klass, "[]", RUBY_METHOD_FUNC(rb_aref), 1); + rb_define_method(rb_klass, "to_ary", RUBY_METHOD_FUNC(rb_to_ary), 0); + rb_define_alias(rb_klass, "to_a", "to_ary"); +} + __NAMESPACE_END_CVTWOPOINTS __NAMESPACE_END_OPENCV + diff --git a/ext/cvtwopoints.h b/ext/opencv/cvtwopoints.h similarity index 81% rename from ext/cvtwopoints.h rename to ext/opencv/cvtwopoints.h index dc28a94b..2a1787a3 100644 --- a/ext/cvtwopoints.h +++ b/ext/opencv/cvtwopoints.h @@ -12,12 +12,12 @@ #include "opencv.h" -#define __NAMESPACE_BEGIN_CVTWOPOINTS namespace cCvTwoPoints{ +#define __NAMESPACE_BEGIN_CVTWOPOINTS namespace cCvTwoPoints { #define __NAMESPACE_END_CVTWOPOINTS } __NAMESPACE_BEGIN_OPENCV -typedef struct CvTwoPoints{ +typedef struct CvTwoPoints { CvPoint p1; CvPoint p2; } CvTwoPoints; @@ -26,12 +26,13 @@ __NAMESPACE_BEGIN_CVTWOPOINTS VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_allocate(VALUE klass); VALUE rb_point1(VALUE self); VALUE rb_point2(VALUE self); +VALUE rb_aref(VALUE self, VALUE index); VALUE rb_to_ary(VALUE self); VALUE new_object(CvTwoPoints twopoints); @@ -39,7 +40,7 @@ VALUE new_object(CvTwoPoints twopoints); __NAMESPACE_END_CVTWOPOINTS inline CvTwoPoints* -CVTWOPOINTS(VALUE object){ +CVTWOPOINTS(VALUE object) { CvTwoPoints *ptr; Data_Get_Struct(object, CvTwoPoints, ptr); return ptr; diff --git a/ext/opencv/cvutils.cpp b/ext/opencv/cvutils.cpp new file mode 100644 index 00000000..3f5342ad --- /dev/null +++ b/ext/opencv/cvutils.cpp @@ -0,0 +1,192 @@ +/************************************************************ + + cvutils.cpp - + + $Author: ser1zw $ + + Copyright (C) 2011 ser1zw + +************************************************************/ +#include "cvutils.h" + +void +raise_typeerror(VALUE object, VALUE expected_class) +{ + raise_typeerror(object, rb_class2name(expected_class)); +} + +void +raise_typeerror(VALUE object, const char* expected_class_name) +{ + rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", + rb_obj_classname(object), expected_class_name); +} + +void +raise_compatible_typeerror(VALUE object, VALUE expected_class) +{ + raise_compatible_typeerror(object, rb_class2name(expected_class)); +} + +void +raise_compatible_typeerror(VALUE object, const char* expected_class_name) +{ + rb_raise(rb_eTypeError, "wrong argument type %s (expected %s or compatible object)", + rb_obj_classname(object), expected_class_name); +} + +/* + * Allocates a memory buffer + * see cv::fastMalloc() + */ +void* +rbFastMalloc(size_t size) +{ + uchar* udata = (uchar*)xmalloc(size + sizeof(void*) + CV_MALLOC_ALIGN); + if(!udata) { + rb_raise(rb_eNoMemError, "Failed to allocate memory"); + } + uchar** adata = cv::alignPtr((uchar**)udata + 1, CV_MALLOC_ALIGN); + adata[-1] = udata; + return adata; +} + +/* + * Allocates a memory buffer + * When memory allocation is failed, run GC and retry it + */ +void* +rb_cvAlloc(size_t size) +{ + return rbFastMalloc(size); +} + +/* + * Creates CvMat and underlying data + * When memory allocation is failed, run GC and retry it + */ +CvMat* +rb_cvCreateMat(int rows, int cols, int type) +{ + CvMat* mat = NULL; + try { + mat = cvCreateMatHeader(rows, cols, type); + if (mat) { + // see OpenCV's cvCreateData() + size_t step = mat->step; + size_t total_size = step * mat->rows + sizeof(int) + CV_MALLOC_ALIGN; + + mat->refcount = (int*)rbFastMalloc(total_size); + mat->data.ptr = (uchar*)cvAlignPtr(mat->refcount + 1, CV_MALLOC_ALIGN); + *mat->refcount = 1; + } + else { + rb_raise(rb_eRuntimeError, "Failed to create mat header"); + } + } + catch(cv::Exception& e) { + if (mat) { + cvReleaseMat(&mat); + } + rb_raise(rb_eRuntimeError, "%s", e.what()); + } + return mat; +} + +/* + * Create IplImage header and allocate underlying data + * When memory allocation is failed, run GC and retry it + */ +IplImage* +rb_cvCreateImage(CvSize size, int depth, int channels) +{ + IplImage* ptr = NULL; + try { + ptr = cvCreateImageHeader(size, depth, channels); + if (ptr) { + // see OpenCV's cvCreateData() + ptr->imageData = ptr->imageDataOrigin = (char*)rbFastMalloc((size_t)ptr->imageSize); + } + else { + rb_raise(rb_eRuntimeError, "Failed to create image header"); + } + } + catch(cv::Exception& e) { + if (ptr) { + cvReleaseImage(&ptr); + } + rb_raise(rb_eRuntimeError, "%s", e.what()); + } + return ptr; +} + +/* + * Creates a structuring element + * When memory allocation is failed, run GC and retry it + */ +IplConvKernel* +rb_cvCreateStructuringElementEx(int cols, int rows, + int anchorX, int anchorY, + int shape, int *values) +{ + IplConvKernel* ptr = NULL; + try { + ptr = cvCreateStructuringElementEx(cols, rows, anchorX, anchorY, shape, values); + } + catch(cv::Exception& e) { + if (e.code != CV_StsNoMem) + rb_raise(rb_eRuntimeError, "%s", e.what()); + + rb_gc_start(); + try { + ptr = cvCreateStructuringElementEx(cols, rows, anchorX, anchorY, shape, values); + } + catch (cv::Exception& e) { + if (e.code == CV_StsNoMem) + rb_raise(rb_eNoMemError, "%s", e.what()); + else + rb_raise(rb_eRuntimeError, "%s", e.what()); + } + } + return ptr; +} + +/* + * Creates memory storage + * When memory allocation is failed, run GC and retry it + */ +CvMemStorage* +rb_cvCreateMemStorage(int block_size) +{ + CvMemStorage* ptr = NULL; + try { + ptr = cvCreateMemStorage(block_size); + } + catch(cv::Exception& e) { + if (e.code != CV_StsNoMem) + rb_raise(rb_eRuntimeError, "%s", e.what()); + + rb_gc_start(); + try { + ptr = cvCreateMemStorage(block_size); + } + catch (cv::Exception& e) { + if (e.code == CV_StsNoMem) + rb_raise(rb_eNoMemError, "%s", e.what()); + else + rb_raise(rb_eRuntimeError, "%s", e.what()); + } + } + return ptr; +} + +VALUE +rb_get_option_table(VALUE klass, const char* table_name, VALUE option) +{ + VALUE table = rb_const_get(klass, rb_intern(table_name)); + if (NIL_P(option)) + return table; + else + return rb_funcall(table, rb_intern("merge"), 1, option); +} + diff --git a/ext/opencv/cvutils.h b/ext/opencv/cvutils.h new file mode 100644 index 00000000..dad9e358 --- /dev/null +++ b/ext/opencv/cvutils.h @@ -0,0 +1,30 @@ +/************************************************************ + + cvutils.h - + + $Author: ser1zw $ + + Copyright (C) 2011 ser1zw + +************************************************************/ + +#include +#include "opencv2/core/core_c.h" +#include "opencv2/core/core.hpp" +#include "opencv2/core/internal.hpp" +#include "opencv2/imgproc/imgproc_c.h" +#include "opencv2/imgproc/imgproc.hpp" + +#define raise_cverror(e) cCvError::raise(e) + +void raise_typeerror(VALUE object, VALUE expected_class); +void raise_typeerror(VALUE object, const char* expected_class_name); +void raise_compatible_typeerror(VALUE object, VALUE expected_class); +void raise_compatible_typeerror(VALUE object, const char* expected_class_name); +void* rb_cvAlloc(size_t size); +CvMat* rb_cvCreateMat(int height, int width, int type); +IplImage* rb_cvCreateImage(CvSize size, int depth, int channels); +IplConvKernel* rb_cvCreateStructuringElementEx(int cols, int rows, int anchorX, int anchorY, int shape, int *values); +CvMemStorage* rb_cvCreateMemStorage(int block_size); +VALUE rb_get_option_table(VALUE klass, const char* table_name, VALUE option); + diff --git a/ext/cvvideowriter.cpp b/ext/opencv/cvvideowriter.cpp similarity index 60% rename from ext/cvvideowriter.cpp rename to ext/opencv/cvvideowriter.cpp index dad0df16..dcd55317 100644 --- a/ext/cvvideowriter.cpp +++ b/ext/opencv/cvvideowriter.cpp @@ -26,27 +26,10 @@ rb_class() return rb_klass; } -void -define_ruby_class() -{ - if(rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - rb_klass = rb_define_class_under(opencv, "CvVideoWriter", rb_cObject); - rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); - rb_define_method(rb_klass, "write", RUBY_METHOD_FUNC(rb_write), 1); - rb_define_method(rb_klass, "close", RUBY_METHOD_FUNC(rb_close), 0); -} - /* * call-seq: - * CvVideoWriter.new(filanem, fourcc, fps, size) -> cvvideowriter - * CvVideoWriter.new(filanem, fourcc, fps, size){|vw| ... } -> nil + * CvVideoWriter.new(filname, fourcc, fps, size[, is_color]) -> cvvideowriter + * CvVideoWriter.new(filname, fourcc, fps, size[, is_color]){|vw| ... } -> nil * * Open new video writer. If block given, writer is closed automatically when end of block. * @@ -55,48 +38,63 @@ define_ruby_class() VALUE rb_initialize(int argc, VALUE *argv, VALUE self) { - VALUE filename, fourcc, fps, size; - rb_scan_args(argc, argv, "40", &filename, &fourcc, &fps, &size); + VALUE filename, fourcc, fps, size, is_color_val; + rb_scan_args(argc, argv, "41", &filename, &fourcc, &fps, &size, &is_color_val); char codec[4] = {' ', ' ', ' ', ' '}; int codec_number; Check_Type(filename, T_STRING); - if (RSTRING(filename)->len == 0) + if (RSTRING_LEN(filename) == 0) rb_raise(rb_eArgError, "argument 1 (file name) dose not given"); if (NIL_P(fourcc)) codec_number = -1; else { Check_Type(fourcc, T_STRING); - if (RSTRING(fourcc)->len > 4) + if (RSTRING_LEN(fourcc) > 4) rb_raise(rb_eStandardError, "argument 2 (fourcc) should be specific 4-character. (i.e \"PIM1\",\"MJPG\")"); else { - for (int i = 0; i < RSTRING(fourcc)->len; i++) - codec[i] = RSTRING(fourcc)->ptr[i]; + int len = RSTRING_LEN(fourcc); + for (int i = 0; i < len; ++i) + codec[i] = RSTRING_PTR(fourcc)[i]; codec_number = CV_FOURCC(codec[0], codec[1], codec[2], codec[3]); } } - DATA_PTR(self) = cvCreateVideoWriter(StringValueCStr(filename), codec_number, FIX2INT(fps), VALUE_TO_CVSIZE(size)); + int is_color; + if (NIL_P(is_color_val)) + is_color = 1; + else + is_color = (is_color_val == Qtrue) ? 1 : 0; + try { + DATA_PTR(self) = cvCreateVideoWriter(StringValueCStr(filename), codec_number, + NUM2DBL(fps), VALUE_TO_CVSIZE(size), is_color); + } + catch (cv::Exception& e) { + raise_cverror(e); + } if (rb_block_given_p()) { rb_yield(self); rb_close(self); return Qnil; - } else { - return self; } + else + return self; } /* * call-seq: - * write(frame) + * write(frame) * * Write image as frame of video stream. - * frame should be CvMat or subclass. + * frame should be IplImage */ VALUE rb_write(VALUE self, VALUE frame) { - if (!rb_obj_is_kind_of(frame, cCvMat::rb_class())) - rb_raise(rb_eTypeError, "argument 1 (frame) should be %s or subclass", rb_class2name(cCvMat::rb_class())); - cvWriteFrame(CVVIDEOWRITER(self), IPLIMAGE(frame)); + try { + cvWriteFrame(CVVIDEOWRITER(self), IPLIMAGE_WITH_CHECK(frame)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } return self; } @@ -107,10 +105,38 @@ VALUE rb_close(VALUE self) { CvVideoWriter *writer = CVVIDEOWRITER(self); - cvReleaseVideoWriter(&writer); + try { + if (writer) + cvReleaseVideoWriter(&writer); + } + catch (cv::Exception& e) { + raise_cverror(e); + } return Qnil; } +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + rb_klass = rb_define_class_under(opencv, "CvVideoWriter", rb_cObject); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "write", RUBY_METHOD_FUNC(rb_write), 1); + rb_define_method(rb_klass, "close", RUBY_METHOD_FUNC(rb_close), 0); +} __NAMESPACE_END_CVVIDEOWRITER __NAMESPACE_END_OPENCV + diff --git a/ext/cvvideowriter.h b/ext/opencv/cvvideowriter.h similarity index 80% rename from ext/cvvideowriter.h rename to ext/opencv/cvvideowriter.h index 0f0a788f..9e99daff 100644 --- a/ext/cvvideowriter.h +++ b/ext/opencv/cvvideowriter.h @@ -12,7 +12,7 @@ #include "opencv.h" -#define __NAMESPACE_BEGIN_CVVIDEOWRITER namespace cCvVideoWriter{ +#define __NAMESPACE_BEGIN_CVVIDEOWRITER namespace cCvVideoWriter { #define __NAMESPACE_END_CVVIDEOWRITER } __NAMESPACE_BEGIN_OPENCV @@ -20,7 +20,7 @@ __NAMESPACE_BEGIN_CVVIDEOWRITER VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_initialize(int argc, VALUE *argv, VALUE self); VALUE rb_write(VALUE self, VALUE frame); @@ -31,9 +31,11 @@ __NAMESPACE_END_CVVIDEOWRITER inline CvVideoWriter* CVVIDEOWRITER(VALUE object) { - CvVideoWriter *ptr; - Data_Get_Struct(object, CvVideoWriter, ptr); - return ptr; + // CvVideoWriter is + // CvVideoWriter *ptr; + // Data_Get_Struct(object, CvVideoWriter, ptr); + // return ptr; + return (CvVideoWriter*)DATA_PTR(object); } __NAMESPACE_END_OPENCV diff --git a/ext/opencv/eigenfaces.cpp b/ext/opencv/eigenfaces.cpp new file mode 100644 index 00000000..69beb794 --- /dev/null +++ b/ext/opencv/eigenfaces.cpp @@ -0,0 +1,75 @@ +/************************************************************ + + eigenfaces.cpp - + + $Author: ser1zw $ + + Copyright (C) 2013 ser1zw + +************************************************************/ +#include +#include "eigenfaces.h" +/* + * Document-class: OpenCV::EigenFaces + * + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_EIGENFACES + +VALUE rb_klass; + +VALUE +rb_class() +{ + return rb_klass; +} + +/* + * call-seq: + * EigenFaces.new(num_components=0, threshold=DBL_MAX) + */ +VALUE +rb_initialize(int argc, VALUE argv[], VALUE self) +{ + VALUE num_components_val, threshold_val; + rb_scan_args(argc, argv, "02", &num_components_val, &threshold_val); + + int num_components = NIL_P(num_components_val) ? 0 : NUM2INT(num_components_val); + double threshold = NIL_P(threshold_val) ? DBL_MAX : NUM2DBL(threshold_val); + + free(DATA_PTR(self)); + cv::Ptr ptr = cv::createEigenFaceRecognizer(num_components, threshold); + DATA_PTR(self) = ptr; + + cFaceRecognizer::guard_facerecognizer(DATA_PTR(self), ptr); + + return self; +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); + VALUE alghorithm = rb_define_class_under(opencv, "Algorithm", rb_cObject); + VALUE face_recognizer = rb_define_class_under(opencv, "FaceRecognizer", alghorithm); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + VALUE face_recognizer = cFaceRecognizer::rb_class(); + rb_klass = rb_define_class_under(opencv, "EigenFaces", face_recognizer); + rb_define_alloc_func(rb_klass, cFaceRecognizer::allocate_facerecognizer); + rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); +} + +__NAMESPACE_END_EIGENFACES +__NAMESPACE_END_OPENCV + diff --git a/ext/opencv/eigenfaces.h b/ext/opencv/eigenfaces.h new file mode 100644 index 00000000..2884808a --- /dev/null +++ b/ext/opencv/eigenfaces.h @@ -0,0 +1,30 @@ +/************************************************************ + + eigenfaces.h + + $Author: ser1zw $ + + Copyright (C) 2013 ser1zw + +************************************************************/ +#ifndef RUBY_OPENCV_EIGENFACES_H +#define RUBY_OPENCV_EIGENFACES_H + +#include "opencv.h" + +#define __NAMESPACE_BEGIN_EIGENFACES namespace cEigenFaces { +#define __NAMESPACE_END_EIGENFACES } + +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_EIGENFACES + +VALUE rb_class(); + +void init_ruby_class(); +VALUE rb_initialize(int argc, VALUE argv[], VALUE self); + +__NAMESPACE_END_EIGENFACES +__NAMESPACE_END_OPENCV + +#endif // RUBY_OPENCV_EIGENFACES_H + diff --git a/ext/opencv/extconf.rb b/ext/opencv/extconf.rb new file mode 100755 index 00000000..1500fa51 --- /dev/null +++ b/ext/opencv/extconf.rb @@ -0,0 +1,77 @@ +#!/usr/bin/env ruby + +CC = RbConfig::CONFIG['CC'] +if CC =~ /clang/ + RbConfig::MAKEFILE_CONFIG['try_header'] = :try_cpp + RbConfig::CONFIG['CPP'] = "#{CC} -E" +elsif RbConfig::CONFIG['arch'] =~ /mswin32/ + RbConfig::MAKEFILE_CONFIG['try_header'] = :try_cpp + RbConfig::CONFIG['CPP'] = "#{CC} /P" +end + +require "mkmf" + +def cv_version_suffix(incdir) + major, minor, subminor = nil, nil, nil + open("#{incdir}/opencv2/core/version.hpp", 'r') { |f| + f.read.lines.each { |line| + major = $1.to_s if line =~ /\A#define\s+(?:CV_VERSION_EPOCH|CV_MAJOR_VERSION)\s+(\d+)\s*\Z/ + minor = $1.to_s if line =~ /\A#define\s+(?:CV_VERSION_MAJOR|CV_MINOR_VERSION)\s+(\d+)\s*\Z/ + subminor = $1.to_s if line =~ /\A#define\s+(?:CV_VERSION_MINOR|CV_SUBMINOR_VERSION)\s+(\d+)\s*\Z/ + } + } + major + minor + subminor +end + +# Quick fix for 2.0.0 +# @libdir_basename is set to nil and dir_config() sets invalid libdir '${opencv-dir}/' when --with-opencv-dir option passed. +@libdir_basename ||= 'lib' +incdir, libdir = dir_config("opencv", "/usr/local/include", "/usr/local/lib") +dir_config("libxml2", "/usr/include", "/usr/lib") + +opencv_headers = ["opencv2/core/core_c.h", "opencv2/core/core.hpp", "opencv2/imgproc/imgproc_c.h", + "opencv2/imgproc/imgproc.hpp", "opencv2/video/tracking.hpp", "opencv2/features2d/features2d.hpp", + "opencv2/flann/flann.hpp", "opencv2/calib3d/calib3d.hpp", "opencv2/objdetect/objdetect.hpp", + "opencv2/legacy/compat.hpp", "opencv2/legacy/legacy.hpp", "opencv2/highgui/highgui_c.h", + "opencv2/highgui/highgui.hpp", "opencv2/photo/photo.hpp"] +opencv_headers_opt = ["opencv2/nonfree/nonfree.hpp"] + +opencv_libraries = ["opencv_calib3d", "opencv_contrib", "opencv_core", "opencv_features2d", + "opencv_flann", "opencv_highgui", "opencv_imgproc", "opencv_legacy", + "opencv_ml", "opencv_objdetect", "opencv_video", "opencv_photo"] +opencv_libraries_opt = ["opencv_gpu", "opencv_nonfree"] + +puts ">> Check the required libraries..." +if $mswin or $mingw + suffix = cv_version_suffix(incdir) + opencv_libraries.map! { |lib| lib + suffix } + opencv_libraries_opt.map! { |lib| lib + suffix } + have_library("msvcrt") + if $mswin + $CFLAGS << ' /EHsc' + CONFIG['CXXFLAGS'] << ' /EHsc' + end +else + have_library("stdc++") +end + +opencv_libraries.each { |lib| raise "#{lib} not found." unless have_library(lib) } +opencv_libraries_opt.each { |lib| warn "#{lib} not found." unless have_library(lib) } + +# Check the required headers +puts ">> Check the required headers..." +opencv_headers.each { |header| raise "#{header} not found." unless have_header(header) } +opencv_headers_opt.each { |header| warn "#{header} not found." unless have_header(header) } +have_header("stdarg.h") + +if $warnflags + $warnflags.slice!('-Wdeclaration-after-statement') + $warnflags.slice!('-Wimplicit-function-declaration') +end + +# Quick fix for 1.8.7 +$CFLAGS << " -I#{File.dirname(__FILE__)}/ext/opencv" + +# Create Makefile +create_makefile('opencv') + diff --git a/ext/opencv/facerecognizer.cpp b/ext/opencv/facerecognizer.cpp new file mode 100644 index 00000000..952ee8ab --- /dev/null +++ b/ext/opencv/facerecognizer.cpp @@ -0,0 +1,219 @@ +/************************************************************ + + facerecognizer.cpp - + + $Author: ser1zw $ + + Copyright (C) 2013 ser1zw + +************************************************************/ +#include +#include "facerecognizer.h" +/* + * Document-class: OpenCV::FaceRecognizer + * + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_FACERECOGNIZER + +VALUE rb_klass; + +std::map > ptr_guard_map; + +void +guard_facerecognizer(void* data_ptr, cv::Ptr ptr) +{ + ptr_guard_map[data_ptr] = ptr; +} + +void +release_facerecognizer(void *data_ptr) +{ + ptr_guard_map[data_ptr].release(); + ptr_guard_map.erase(data_ptr); +} + +VALUE +allocate_facerecognizer(VALUE klass) +{ + return Data_Wrap_Struct(klass, 0, release_facerecognizer, NULL); +} + + +VALUE +rb_class() +{ + return rb_klass; +} + +/* + * call-seq: + * train(src, labels) + * + * Trains a FaceRecognizer with given data and associated labels. + */ +VALUE +rb_train(VALUE self, VALUE src, VALUE labels) +{ + Check_Type(src, T_ARRAY); + Check_Type(labels, T_ARRAY); + + VALUE *src_ptr = RARRAY_PTR(src); + int src_size = RARRAY_LEN(src); + std::vector images; + for (int i = 0; i < src_size; i++) { + images.push_back(cv::Mat(CVMAT_WITH_CHECK(src_ptr[i]))); + } + + VALUE *labels_ptr = RARRAY_PTR(labels); + int labels_size = RARRAY_LEN(labels); + std::vector local_labels; + for (int i = 0; i < labels_size; i++) { + local_labels.push_back(NUM2INT(labels_ptr[i])); + } + + cv::FaceRecognizer *self_ptr = FACERECOGNIZER(self); + try { + self_ptr->train(images, local_labels); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return Qnil; +} + +/* + * call-seq: + * udpate(src, labels) + * + * Updates a FaceRecognizer with given data and associated labels. Only valid on LBPH models. + */ +VALUE +rb_update(VALUE self, VALUE src, VALUE labels) +{ + Check_Type(src, T_ARRAY); + Check_Type(labels, T_ARRAY); + + VALUE *src_ptr = RARRAY_PTR(src); + int src_size = RARRAY_LEN(src); + std::vector images; + for (int i = 0; i < src_size; i++) { + images.push_back(cv::Mat(CVMAT_WITH_CHECK(src_ptr[i]))); + } + + VALUE *labels_ptr = RARRAY_PTR(labels); + int labels_size = RARRAY_LEN(labels); + std::vector local_labels; + for (int i = 0; i < labels_size; i++) { + local_labels.push_back(NUM2INT(labels_ptr[i])); + } + + cv::FaceRecognizer *self_ptr = FACERECOGNIZER(self); + try { + self_ptr->update(images, local_labels); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return Qnil; +} + +/* + * call-seq: + * predict(src) + * + * Predicts a label and associated confidence (e.g. distance) for a given input image. + */ +VALUE +rb_predict(VALUE self, VALUE src) +{ + cv::Mat mat = cv::Mat(CVMAT_WITH_CHECK(src)); + cv::FaceRecognizer *self_ptr = FACERECOGNIZER(self); + int label; + double confidence; + try { + self_ptr->predict(mat, label, confidence); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return rb_ary_new3(2, INT2NUM(label), DBL2NUM(confidence)); +} + + +/* + * call-seq: + * save(filename) + * + * Saves this model to a given filename, either as XML or YAML. + */ +VALUE +rb_save(VALUE self, VALUE filename) +{ + Check_Type(filename, T_STRING); + cv::FaceRecognizer *self_ptr = FACERECOGNIZER(self); + try { + char* s = StringValueCStr(filename); + self_ptr->save(std::string(s)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return Qnil; +} + +/* + * call-seq: + * load(filename) + * + * Loads a FaceRecognizer and its model state. + */ +VALUE +rb_load(VALUE self, VALUE filename) +{ + Check_Type(filename, T_STRING); + cv::FaceRecognizer *self_ptr = FACERECOGNIZER(self); + try { + char* s = StringValueCStr(filename); + self_ptr->load(std::string(s)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return Qnil; +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); + VALUE alghorithm = rb_define_class_under(opencv, "Algorithm", rb_cObject); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + VALUE alghorithm = cAlgorithm::rb_class(); + rb_klass = rb_define_class_under(opencv, "FaceRecognizer", alghorithm); + rb_define_method(rb_klass, "train", RUBY_METHOD_FUNC(rb_train), 2); + rb_define_method(rb_klass, "update", RUBY_METHOD_FUNC(rb_update), 2); + rb_define_method(rb_klass, "predict", RUBY_METHOD_FUNC(rb_predict), 1); + rb_define_method(rb_klass, "save", RUBY_METHOD_FUNC(rb_save), 1); + rb_define_method(rb_klass, "load", RUBY_METHOD_FUNC(rb_load), 1); +} + +__NAMESPACE_END_FACERECOGNIZER +__NAMESPACE_END_OPENCV + diff --git a/ext/opencv/facerecognizer.h b/ext/opencv/facerecognizer.h new file mode 100644 index 00000000..2d170597 --- /dev/null +++ b/ext/opencv/facerecognizer.h @@ -0,0 +1,46 @@ +/************************************************************ + + facerecognizer.h + + $Author: ser1zw $ + + Copyright (C) 2013 ser1zw + +************************************************************/ +#ifndef RUBY_OPENCV_FACERECOGNIZER_H +#define RUBY_OPENCV_FACERECOGNIZER_H + +#include "opencv.h" + +#define __NAMESPACE_BEGIN_FACERECOGNIZER namespace cFaceRecognizer { +#define __NAMESPACE_END_FACERECOGNIZER } + +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_FACERECOGNIZER + +VALUE rb_class(); + +void init_ruby_class(); +VALUE rb_train(VALUE self, VALUE src, VALUE labels); +VALUE rb_predict(VALUE self, VALUE src); +VALUE rb_save(VALUE self, VALUE filename); +VALUE rb_load(VALUE self, VALUE filename); + +void guard_facerecognizer(void* data_ptr, cv::Ptr ptr); +void release_facerecognizer(void *data_ptr); +VALUE allocate_facerecognizer(VALUE klass); + +__NAMESPACE_END_FACERECOGNIZER + +inline cv::FaceRecognizer* +FACERECOGNIZER(VALUE object) +{ + cv::FaceRecognizer *ptr; + Data_Get_Struct(object, cv::FaceRecognizer, ptr); + return ptr; +} + +__NAMESPACE_END_OPENCV + +#endif // RUBY_OPENCV_FACERECOGNIZER_H + diff --git a/ext/opencv/fisherfaces.cpp b/ext/opencv/fisherfaces.cpp new file mode 100644 index 00000000..503afe47 --- /dev/null +++ b/ext/opencv/fisherfaces.cpp @@ -0,0 +1,75 @@ +/************************************************************ + + fisherfaces.cpp - + + $Author: ser1zw $ + + Copyright (C) 2013 ser1zw + +************************************************************/ +#include +#include "fisherfaces.h" +/* + * Document-class: OpenCV::FisherFaces + * + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_FISHERFACES + +VALUE rb_klass; + +VALUE +rb_class() +{ + return rb_klass; +} + +/* + * call-seq: + * FisherFaces.new(num_components=0, threshold=DBL_MAX) + */ +VALUE +rb_initialize(int argc, VALUE argv[], VALUE self) +{ + VALUE num_components_val, threshold_val; + rb_scan_args(argc, argv, "02", &num_components_val, &threshold_val); + + int num_components = NIL_P(num_components_val) ? 0 : NUM2INT(num_components_val); + double threshold = NIL_P(threshold_val) ? DBL_MAX : NUM2DBL(threshold_val); + + free(DATA_PTR(self)); + cv::Ptr ptr = cv::createFisherFaceRecognizer(num_components, threshold); + DATA_PTR(self) = ptr; + + cFaceRecognizer::guard_facerecognizer(DATA_PTR(self), ptr); + + return self; +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); + VALUE alghorithm = rb_define_class_under(opencv, "Algorithm", rb_cObject); + VALUE face_recognizer = rb_define_class_under(opencv, "FaceRecognizer", alghorithm); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + VALUE face_recognizer = cFaceRecognizer::rb_class(); + rb_klass = rb_define_class_under(opencv, "FisherFaces", face_recognizer); + rb_define_alloc_func(rb_klass, cFaceRecognizer::allocate_facerecognizer); + rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); +} + +__NAMESPACE_END_FISHERFACES +__NAMESPACE_END_OPENCV + diff --git a/ext/opencv/fisherfaces.h b/ext/opencv/fisherfaces.h new file mode 100644 index 00000000..dea9e6fe --- /dev/null +++ b/ext/opencv/fisherfaces.h @@ -0,0 +1,30 @@ +/************************************************************ + + fisherfaces.h + + $Author: ser1zw $ + + Copyright (C) 2013 ser1zw + +************************************************************/ +#ifndef RUBY_OPENCV_FISHERFACES_H +#define RUBY_OPENCV_FISHERFACES_H + +#include "opencv.h" + +#define __NAMESPACE_BEGIN_FISHERFACES namespace cFisherFaces { +#define __NAMESPACE_END_FISHERFACES } + +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_FISHERFACES + +VALUE rb_class(); + +void init_ruby_class(); +VALUE rb_initialize(int argc, VALUE argv[], VALUE self); + +__NAMESPACE_END_FISHERFACES +__NAMESPACE_END_OPENCV + +#endif // RUBY_OPENCV_FISHERFACES_H + diff --git a/ext/gui.cpp b/ext/opencv/gui.cpp similarity index 59% rename from ext/gui.cpp rename to ext/opencv/gui.cpp index 5845c700..bff86f5b 100644 --- a/ext/gui.cpp +++ b/ext/opencv/gui.cpp @@ -7,14 +7,9 @@ Copyright (C) 2005-2006 Masakazu Yonekura ************************************************************/ -#ifdef HAVE_CALLBACK_H - #include "gui.h" /* * Document-module: OpenCV::GUI - * - * OpenCV simple GUI interface. Provides Window, Trackbar. - * This GUI work on GTK or Microsoft Windows native GUI. */ __NAMESPACE_BEGIN_OPENCV __NAMESPACE_BEGIN_GUI @@ -27,10 +22,39 @@ rb_module_GUI() return rb_module; } +/* + * Waits for a pressed key. + * + * @overload wait_key(delay = 0) + * @param delay [Integer] Delay in milliseconds. 0 is the special value that means "forever". + * @return [Number] The code of the pressed key or nil if no key was pressed + * before the specified time had elapsed. + * @opencv_func cvWaitKey + */ +VALUE +rb_wait_key(int argc, VALUE *argv, VALUE self) +{ + VALUE delay; + rb_scan_args(argc, argv, "01", &delay); + int keycode = 0; + try { + keycode = cvWaitKey(IF_INT(delay, 0)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return (keycode < 0) ? Qnil : INT2NUM(keycode); +} + void -define_ruby_module() +init_ruby_module() { - if(rb_module) +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_module) return; /* * opencv = rb_define_module("OpenCV"); @@ -42,24 +66,6 @@ define_ruby_module() rb_define_singleton_method(rb_module, "wait_key", RUBY_METHOD_FUNC(rb_wait_key), -1); } -/* - * call-seq: - * wait_key([delay]) -> int or nil - * - * Waits for a pressed key each GUI wedget. - * Return the code of the pressed key or nil if no key were pressed until the specified timeout has elapsed. - * delay should be Fixnum. Wait delay millisecond. - */ -VALUE -rb_wait_key(int argc, VALUE *argv, VALUE self) -{ - VALUE delay; - rb_scan_args(argc, argv, "01", &delay); - int keycode = 0; - return ((keycode = cvWaitKey(IF_INT(delay, 0))) < 0) ? Qnil : INT2FIX(keycode); -} - __NAMESPACE_END_GUI __NAMESPACE_END_OPENCV -#endif // HAVE_CALLBACK_H diff --git a/ext/gui.h b/ext/opencv/gui.h similarity index 80% rename from ext/gui.h rename to ext/opencv/gui.h index e4924aaf..486c0769 100644 --- a/ext/gui.h +++ b/ext/opencv/gui.h @@ -7,21 +7,19 @@ Copyright (C) 2005-2006 Masakazu Yonekura ************************************************************/ -#ifdef HAVE_CALLBACK_H - -#define __NAMESPACE_BEGIN_GUI namespace mGUI{ -#define __NAMESPACE_END_GUI } - #ifndef RUBY_OPENCV_GUI_H #define RUBY_OPENCV_GUI_H +#define __NAMESPACE_BEGIN_GUI namespace mGUI { +#define __NAMESPACE_END_GUI } + #include "opencv.h" __NAMESPACE_BEGIN_OPENCV __NAMESPACE_BEGIN_GUI VALUE rb_module_GUI(); -void define_ruby_module(); +void init_ruby_module(); VALUE rb_wait_key(int argc, VALUE *argv, VALUE self); @@ -30,4 +28,3 @@ __NAMESPACE_END_OPENCV #endif // RUBY_OPENCV_GUI_H -#endif // HAVE_CALLBACK_H diff --git a/ext/iplconvkernel.cpp b/ext/opencv/iplconvkernel.cpp similarity index 70% rename from ext/iplconvkernel.cpp rename to ext/opencv/iplconvkernel.cpp index b0a10547..8b2d32f0 100644 --- a/ext/iplconvkernel.cpp +++ b/ext/opencv/iplconvkernel.cpp @@ -7,7 +7,7 @@ Copyright (C) 2005-2006 Masakazu Yonekura ************************************************************/ -#include"iplconvkernel.h" +#include "iplconvkernel.h" /* * Document-class: OpenCV::IplConvKernel * @@ -29,46 +29,17 @@ rb_class() return rb_klass; } -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - rb_klass = rb_define_class_under(opencv, "IplConvKernel", rb_cObject); - rb_define_alloc_func(rb_klass, rb_allocate); - - rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); - rb_define_method(rb_klass, "size", RUBY_METHOD_FUNC(rb_size), 0); - rb_define_method(rb_klass, "cols", RUBY_METHOD_FUNC(rb_cols), 0); - rb_define_alias(rb_klass, "columns", "cols"); - rb_define_method(rb_klass, "rows", RUBY_METHOD_FUNC(rb_rows), 0); - rb_define_method(rb_klass, "anchor", RUBY_METHOD_FUNC(rb_anchor), 0); - rb_define_method(rb_klass, "anchor_x", RUBY_METHOD_FUNC(rb_anchor_x), 0); - rb_define_method(rb_klass, "anchor_y", RUBY_METHOD_FUNC(rb_anchor_y), 0); -} - VALUE rb_allocate(VALUE klass) { - return OPENCV_OBJECT(klass, 0); + return IPLCONVKERNEL_OBJECT(klass, 0); } /* * call-seq: - * IplConvKernel.new(shape, rows, cols, anchor_x, anchor_y) + * IplConvKernel.new(cols, rows, anchor_x, anchor_y, shape [,values = nil]) * * Creates structuring element. - * shape - * Shape of the structuring element; may have the following values: - * :rect - * :cross - * :ellipse * cols * Number of columns in the structuring element. * rows @@ -77,25 +48,45 @@ rb_allocate(VALUE klass) * Relative horizontal offset of the anchor point. * anchor_y * Relative vertical offset of the anchor point. + * shape + * Shape of the structuring element; may have the following values: + * :rect + * :cross + * :ellipse + * :custom * */ VALUE rb_initialize(int argc, VALUE *argv, VALUE self) { - VALUE shape, rows, cols, anchor_x, anchor_y; - rb_scan_args(argc, argv, "50", &shape, &rows, &cols, &anchor_x, &anchor_y); - Check_Type(shape, T_SYMBOL); - const char *shape_name = rb_id2name(SYM2ID(shape)); - int shape_type = 0; - if (!strcmp(shape_name, "rect")) - shape_type = CV_SHAPE_RECT; - else if (!strcmp(shape_name, "corss")) - shape_type = CV_SHAPE_CROSS; - else if (!strcmp(shape_name, "ellipse")) - shape_type = CV_SHAPE_ELLIPSE; - else - rb_raise(rb_eTypeError, "argument 1 (shape) should be :rect or :cross or :ellipse."); - DATA_PTR(self) = cvCreateStructuringElementEx(NUM2INT(cols), NUM2INT(rows), NUM2INT(anchor_x), NUM2INT(anchor_y), shape_type); + VALUE shape, rows, cols, anchor_x, anchor_y, values; + rb_scan_args(argc, argv, "51", &cols, &rows, &anchor_x, &anchor_y, &shape, &values); + int shape_type; + int _cols = NUM2INT(cols); + int _rows = NUM2INT(rows); + int num_values; + int *_values = NULL; + const int INVALID_SHAPE = -1; + + shape_type = CVMETHOD("STRUCTURING_ELEMENT_SHAPE", shape, INVALID_SHAPE); + if (shape_type == INVALID_SHAPE) + rb_raise(rb_eTypeError, "argument 1 (shape) should be :rect or :cross or :ellipse or :custom."); + if (shape_type == CV_SHAPE_CUSTOM) { + if (NIL_P(values)) + rb_raise(rb_eArgError, "argument 6 (values) should not be nil when the shape is :custom."); + num_values = RARRAY_LEN(values); + _values = RB_ALLOC_N(int, num_values); + VALUE *values_ptr = RARRAY_PTR(values); + for (int i = 0; i < num_values; ++i) + _values[i] = NUM2INT(values_ptr[i]); + } + try { + DATA_PTR(self) = rb_cvCreateStructuringElementEx(_cols, _rows, NUM2INT(anchor_x), NUM2INT(anchor_y), + shape_type, _values); + } + catch (cv::Exception& e) { + raise_cverror(e); + } return self; } @@ -173,5 +164,35 @@ rb_anchor_y(VALUE self) return INT2NUM(IPLCONVKERNEL(self)->anchorY); } +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + rb_klass = rb_define_class_under(opencv, "IplConvKernel", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "size", RUBY_METHOD_FUNC(rb_size), 0); + rb_define_method(rb_klass, "cols", RUBY_METHOD_FUNC(rb_cols), 0); + rb_define_alias(rb_klass, "columns", "cols"); + rb_define_method(rb_klass, "rows", RUBY_METHOD_FUNC(rb_rows), 0); + rb_define_method(rb_klass, "anchor", RUBY_METHOD_FUNC(rb_anchor), 0); + rb_define_method(rb_klass, "anchor_x", RUBY_METHOD_FUNC(rb_anchor_x), 0); + rb_define_method(rb_klass, "anchor_y", RUBY_METHOD_FUNC(rb_anchor_y), 0); +} + __NAMESPACE_END_IPLCONVKERNEL __NAMESPACE_END_OPENCV + diff --git a/ext/iplconvkernel.h b/ext/opencv/iplconvkernel.h similarity index 74% rename from ext/iplconvkernel.h rename to ext/opencv/iplconvkernel.h index d39e2595..59531969 100644 --- a/ext/iplconvkernel.h +++ b/ext/opencv/iplconvkernel.h @@ -12,7 +12,7 @@ #include "opencv.h" -#define __NAMESPACE_BEGIN_IPLCONVKERNEL namespace cIplConvKernel{ +#define __NAMESPACE_BEGIN_IPLCONVKERNEL namespace cIplConvKernel { #define __NAMESPACE_END_IPLCONVKERNEL } __NAMESPACE_BEGIN_OPENCV @@ -21,7 +21,7 @@ __NAMESPACE_BEGIN_IPLCONVKERNEL VALUE rb_class(); VALUE rb_allocate(VALUE klass); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_initialize(int argc, VALUE *argv, VALUE self); VALUE rb_size(VALUE self); VALUE rb_cols(VALUE self); @@ -32,6 +32,23 @@ VALUE rb_anchor_y(VALUE self); __NAMESPACE_END_IPLCONVKERNEL +inline IplConvKernel* +IPLCONVKERNEL(VALUE object) +{ + IplConvKernel *ptr; + Data_Get_Struct(object, IplConvKernel, ptr); + return ptr; +} + +inline IplConvKernel* +IPLCONVKERNEL_WITH_CHECK(VALUE object) +{ + if (!rb_obj_is_kind_of(object, cIplConvKernel::rb_class())) + raise_typeerror(object, cIplConvKernel::rb_class()); + return IPLCONVKERNEL(object); +} + +/* inline IplConvKernel* IPLCONVKERNEL(VALUE object) { @@ -41,11 +58,13 @@ IPLCONVKERNEL(VALUE object) else if (rb_obj_is_kind_of(object, cIplConvKernel::rb_class())) { Data_Get_Struct(object, IplConvKernel, ptr); return ptr; - } else { + } + else { rb_warn("invalid kernel. use default kernel (3x3 rectangle)."); return NULL; } } +*/ __NAMESPACE_END_OPENCV diff --git a/ext/opencv/iplimage.cpp b/ext/opencv/iplimage.cpp new file mode 100644 index 00000000..adc97a0d --- /dev/null +++ b/ext/opencv/iplimage.cpp @@ -0,0 +1,651 @@ +/************************************************************ + + iplimage.cpp - + + $Author: lsxi $ + + Copyright (C) 2005-2006 Masakazu Yonekura + +************************************************************/ +#include "iplimage.h" +/* + * Document-class: OpenCV::IplImage + * + * IPL(Intel Image Processing Library) Image class. + * + * IplImage is subclass of CvMat. IplImage support ROI(region of interest) and COI(color of interest). + * Most of CvMat method support ROI, and some of CvMat method support COI. + * + * =What is ROI? + * region of interest. + * + * =What is COI? + * color of interest. + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_IPLIMAGE + +VALUE rb_klass; + +VALUE +rb_class() +{ + return rb_klass; +} + +VALUE +rb_allocate(VALUE klass) +{ + return OPENCV_OBJECT(rb_klass, 0); +} + +/* + * call-seq: + * new(width, height[, depth = CV_8U][, channel = 3]) + * + * Create width * height image. Each element-value set 0. + * + * Each element possigle range is set by depth. Default is unsigned 8bit. + * + * Number of channel is set by channel. channel should be 1..4. + * + * note: width = col, height = row, on CvMat. It is noted not to make a mistake + * because the order of argument is differenct to CvMat. + */ +VALUE +rb_initialize(int argc, VALUE *argv, VALUE self) +{ + VALUE width, height, depth, channel; + rb_scan_args(argc, argv, "22", &width, &height, &depth, &channel); + int _depth = CVMETHOD("DEPTH", depth, CV_8U); + int _channel = argc < 4 ? 3 : NUM2INT(channel); + DATA_PTR(self) = rb_cvCreateImage(cvSize(NUM2INT(width), NUM2INT(height)), cvIplDepth(_depth), _channel); + return self; +} + +/* + * call-seq: + * IplImage::load(filename[,iscolor = CV_LOAD_IMAGE_COLOR]) + * + * Load an image from file. + * iscolor = CV_LOAD_IMAGE_COLOR, the loaded image is forced to be a 3-channel color image + * iscolor = CV_LOAD_IMAGE_GRAYSCALE, the loaded image is forced to be grayscale + * iscolor = CV_LOAD_IMAGE_UNCHANGED, the loaded image will be loaded as is. + * Currently the following file format are supported. + * * Windows bitmaps - BMP,DIB + * * JPEG files - JPEG,JPG,JPE + * * Portable Network Graphics - PNG + * * Portable image format - PBM,PGM,PPM + * * Sun rasters - SR,RAS + * * TIFF files - TIFF,TIF + */ +VALUE +rb_load_image(int argc, VALUE *argv, VALUE self) +{ + VALUE filename, iscolor; + rb_scan_args(argc, argv, "11", &filename, &iscolor); + Check_Type(filename, T_STRING); + + int _iscolor; + if (TYPE(iscolor) == T_NIL) { + _iscolor = CV_LOAD_IMAGE_COLOR; + } + else { + Check_Type(iscolor, T_FIXNUM); + _iscolor = FIX2INT(iscolor); + } + + IplImage *image; + if ((image = cvLoadImage(StringValueCStr(filename), _iscolor)) == NULL) { + rb_raise(rb_eStandardError, "file does not exist or invalid format image."); + } + return OPENCV_OBJECT(rb_klass, image); +} + +/* + * call-seq: + * decode_image(buf[, iscolor=CV_LOAD_IMAGE_COLOR]) -> IplImage + * + * Reads an image from a buffer in memory. + * + * Parameters: + * buf - Input array + * iscolor - Flags specifying the color type of a decoded image (the same flags as CvMat#load) + */ +VALUE +rb_decode_image(int argc, VALUE *argv, VALUE self) +{ + int iscolor, need_release; + CvMat* buff = cCvMat::prepare_decoding(argc, argv, &iscolor, &need_release); + IplImage* img_ptr = NULL; + try { + img_ptr = cvDecodeImage(buff, iscolor); + if (need_release) { + cvReleaseMat(&buff); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + return OPENCV_OBJECT(rb_klass, img_ptr); +} + +/* + * Get ROI as CvRect. + */ +VALUE +rb_get_roi(VALUE self) +{ + CvRect rect; + try { + rect = cvGetImageROI(IPLIMAGE(self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return cCvRect::new_object(rect); +} + +/* + * call-seq: + * set_roi(rect) + * set_roi(rect){|image| ...} + * + * Set ROI. rect should be CvRect or compatible object. + * Return self. + */ +VALUE +rb_set_roi(VALUE self, VALUE roi) +{ + VALUE block = rb_block_given_p() ? rb_block_proc() : 0; + try { + if (block) { + CvRect prev_roi = cvGetImageROI(IPLIMAGE(self)); + cvSetImageROI(IPLIMAGE(self), VALUE_TO_CVRECT(roi)); + rb_yield_values(1, self); + cvSetImageROI(IPLIMAGE(self), prev_roi); + } + else { + cvSetImageROI(IPLIMAGE(self), VALUE_TO_CVRECT(roi)); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + + +/* + * Reset ROI setting. Same as IplImage#roi = nil. Return self. + */ +VALUE +rb_reset_roi(VALUE self) +{ + try { + cvResetImageROI(IPLIMAGE(self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Return COI as Integer. + */ +VALUE +rb_get_coi(VALUE self) +{ + int coi = 0; + try { + coi = cvGetImageCOI(IPLIMAGE(self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return INT2FIX(coi); +} + +/* + * call-seq: + * set_coi(coi) + * set_coi(coi){|image| ...} + * + * Set COI. coi should be Integer. + * Return self. + */ +VALUE +rb_set_coi(VALUE self, VALUE coi) +{ + VALUE block = rb_block_given_p() ? rb_block_proc() : 0; + try { + if (block) { + int prev_coi = cvGetImageCOI(IPLIMAGE(self)); + cvSetImageCOI(IPLIMAGE(self), NUM2INT(coi)); + rb_yield_values(1, self); + cvSetImageCOI(IPLIMAGE(self), prev_coi); + } + else { + cvSetImageCOI(IPLIMAGE(self), NUM2INT(coi)); + } + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Reset COI setting. Same as IplImage#coi = 0. Return self. + */ +VALUE +rb_reset_coi(VALUE self) +{ + try { + cvSetImageCOI(IPLIMAGE(self), 0); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * call-seq: + * IplImage.smoothness(lowFreqRatio, blankDensity, messyDensity, highFreqRatio) -> [ symbol, float, float ] + * + * Determines if the image's smoothness is either, :smooth, :messy, or :blank. + * + * Original Author: yuhanz@gmail.com + */ +VALUE +rb_smoothness(int argc, VALUE *argv, VALUE self) +{ + VALUE lowFreqRatio, blankDensity, messyDensity, highFreqRatio; + rb_scan_args(argc, argv, "04", &lowFreqRatio, &blankDensity, &messyDensity, &highFreqRatio); + + double f_lowFreqRatio, f_blankDensity, f_messyDensity, f_highFreqRatio; + double outLowDensity, outHighDensity; + if (TYPE(lowFreqRatio) == T_NIL) { + f_lowFreqRatio = 10 / 128.0f; + } + else { + Check_Type(lowFreqRatio, T_FLOAT); + f_lowFreqRatio = NUM2DBL(lowFreqRatio); + } + if (TYPE(blankDensity) == T_NIL) { + f_blankDensity = 1.2f; + } + else { + Check_Type(blankDensity, T_FLOAT); + f_blankDensity = NUM2DBL(blankDensity); + } + if (TYPE(messyDensity) == T_NIL) { + f_messyDensity = 0.151f; + } + else { + Check_Type(messyDensity, T_FLOAT); + f_messyDensity = NUM2DBL(messyDensity); + } + if (TYPE(highFreqRatio) == T_NIL) { + f_highFreqRatio = 5 / 128.0f; + } + else { + Check_Type(highFreqRatio, T_FLOAT); + f_highFreqRatio = NUM2DBL(highFreqRatio); + } + + IplImage *pFourierImage; + IplImage *p64DepthImage; + + // the image is required to be in depth of 64 + if (IPLIMAGE(self)->depth == 64) { + p64DepthImage = NULL; + pFourierImage = create_fourier_image(IPLIMAGE(self)); + } + else { + p64DepthImage = rb_cvCreateImage(cvGetSize(IPLIMAGE(self)), IPL_DEPTH_64F, 1); + cvConvertScale(CVARR(self), p64DepthImage, 1.0, 0.0); + pFourierImage = create_fourier_image(p64DepthImage); + } + + Smoothness result = compute_smoothness(pFourierImage, f_lowFreqRatio, f_blankDensity, f_messyDensity, + f_highFreqRatio, outLowDensity, outHighDensity); + + cvReleaseImage(&pFourierImage); + if (p64DepthImage != NULL) + cvReleaseImage(&p64DepthImage); + + switch(result) { + case SMOOTH: + return rb_ary_new3(3, ID2SYM(rb_intern("smooth")), rb_float_new(outLowDensity), rb_float_new(outHighDensity)); + case MESSY: + return rb_ary_new3(3, ID2SYM(rb_intern("messy")), rb_float_new(outLowDensity), rb_float_new(outHighDensity)); + case BLANK: + return rb_ary_new3(3, ID2SYM(rb_intern("blank")), rb_float_new(outLowDensity), rb_float_new(outHighDensity)); + default: + return rb_ary_new3(3, NULL, rb_float_new(outLowDensity), rb_float_new(outHighDensity)); + } +} + +/** + * Note: if lowDensity < blankDensityThreshold -> blank; + * else if highDensity > messyDensityThreshold -> messy; + * else -> good; + */ +Smoothness +compute_smoothness(const IplImage *pFourierImage, const double lowFreqRatio, const double blankDensity, + const double messyDensity, const double highFreqRatio, double &outLowDensity, + double &outHighDensity) +{ + int low, high; + IplImage *filteredFourierImage; + int totalIntensity; + double den, totalArea; + CvScalar scalar; + + if (!(pFourierImage->nChannels == 1 && pFourierImage->depth == 64) ) { + cvError(CV_StsUnmatchedSizes, "compute_smoothness", "input image must contain only 1 channel and a depth of 64", + __FILE__, __LINE__ ); + } + + high_pass_range(pFourierImage, lowFreqRatio, low, high ); + totalArea = M_PI * (high * high - low * low); + + filteredFourierImage = create_frequency_filtered_image(pFourierImage, low, high); + scalar = cvSum(filteredFourierImage); + totalIntensity = (int)scalar.val[0]; + cvReleaseImage(&filteredFourierImage); + outLowDensity = den = totalIntensity / totalArea; + + if (den <= blankDensity) { + return BLANK; + } + + low = (int)(high * (1.0 - highFreqRatio)); + + filteredFourierImage = create_frequency_filtered_image(pFourierImage, low, high); + scalar = cvSum(filteredFourierImage); + totalIntensity = (int)scalar.val[0]; + cvReleaseImage(&filteredFourierImage); + outHighDensity = den = totalIntensity / totalArea; + + if (den >= messyDensity) { + return MESSY; + } + + return SMOOTH; +} + +// Rearrange the quadrants of Fourier image so that the origin is at +// the image center +// src & dst arrays of equal size & type +void +cvShiftDFT(CvArr *src_arr, CvArr *dst_arr ) +{ + CvMat *tmp = NULL; + CvMat q1stub, q2stub; + CvMat q3stub, q4stub; + CvMat d1stub, d2stub; + CvMat d3stub, d4stub; + CvMat *q1, *q2, *q3, *q4; + CvMat *d1, *d2, *d3, *d4; + + CvSize size = cvGetSize(src_arr); + CvSize dst_size = cvGetSize(dst_arr); + int cx, cy; + + if (dst_size.width != size.width || + dst_size.height != size.height) { + cvError( CV_StsUnmatchedSizes, "cvShiftDFT", "Source and Destination arrays must have equal sizes", + __FILE__, __LINE__ ); + } + + if (src_arr == dst_arr) { + tmp = rb_cvCreateMat(size.height / 2, size.width / 2, cvGetElemType(src_arr)); + } + + cx = size.width / 2; + cy = size.height / 2; // image center + + q1 = cvGetSubRect(src_arr, &q1stub, cvRect(0,0,cx, cy)); + q2 = cvGetSubRect(src_arr, &q2stub, cvRect(cx,0,cx,cy)); + q3 = cvGetSubRect(src_arr, &q3stub, cvRect(cx,cy,cx,cy)); + q4 = cvGetSubRect(src_arr, &q4stub, cvRect(0,cy,cx,cy)); + d1 = cvGetSubRect(src_arr, &d1stub, cvRect(0,0,cx,cy)); + d2 = cvGetSubRect(src_arr, &d2stub, cvRect(cx,0,cx,cy)); + d3 = cvGetSubRect(src_arr, &d3stub, cvRect(cx,cy,cx,cy)); + d4 = cvGetSubRect(src_arr, &d4stub, cvRect(0,cy,cx,cy)); + + if (src_arr != dst_arr) { + if (!CV_ARE_TYPES_EQ(q1, d1)) { + cvError(CV_StsUnmatchedFormats, "cvShiftDFT", "Source and Destination arrays must have the same format", + __FILE__, __LINE__ ); + } + cvCopy(q3, d1, 0); + cvCopy(q4, d2, 0); + cvCopy(q1, d3, 0); + cvCopy(q2, d4, 0); + } + else { + cvCopy(q3, tmp, 0); + cvCopy(q1, q3, 0); + cvCopy(tmp, q1, 0); + cvCopy(q4, tmp, 0); + cvCopy(q2, q4, 0); + cvCopy(tmp, q2, 0); + } + + if (tmp != NULL) { + cvReleaseMat(&tmp); + } +} + +IplImage* +create_fourier_image(const IplImage *im) +{ + IplImage *realInput; + IplImage *imaginaryInput; + IplImage *complexInput; + int dft_M, dft_N; + CvMat *dft_A, tmp; + IplImage *image_Re; + IplImage *image_Im; + + realInput = rb_cvCreateImage(cvGetSize(im), IPL_DEPTH_64F, 1); + imaginaryInput = rb_cvCreateImage(cvGetSize(im), IPL_DEPTH_64F, 1); + complexInput = rb_cvCreateImage(cvGetSize(im), IPL_DEPTH_64F, 2); + + cvScale(im, realInput, 1.0, 0.0); + cvZero(imaginaryInput); + cvMerge(realInput, imaginaryInput, NULL, NULL, complexInput); + + dft_M = cvGetOptimalDFTSize(im->height - 1); + dft_N = cvGetOptimalDFTSize(im->width - 1); + + dft_A = rb_cvCreateMat(dft_M, dft_N, CV_64FC2); + image_Re = rb_cvCreateImage(cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1); + image_Im = rb_cvCreateImage(cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1); + + // copy A to dft_A and pad dft_A with zeros + cvGetSubRect(dft_A, &tmp, cvRect(0,0, im->width, im->height)); + cvCopy(complexInput, &tmp, NULL); + if (dft_A->cols > im->width) { + cvGetSubRect(dft_A, &tmp, cvRect(im->width,0, dft_A->cols - im->width, im->height)); + cvZero(&tmp); + } + + // no need to pad bottom part of dft_A with zeros because of + // use nonzero_rows parameter in cvDFT() call below + + cvDFT(dft_A, dft_A, CV_DXT_FORWARD, complexInput->height); + + // Split Fourier in real and imaginary parts + cvSplit(dft_A, image_Re, image_Im, 0, 0); + + // Compute the magnitude of the spectrum Mag = sqrt(Re^2 + Im^2) + cvPow(image_Re, image_Re, 2.0); + cvPow(image_Im, image_Im, 2.0); + cvAdd(image_Re, image_Im, image_Re, NULL); + cvPow(image_Re, image_Re, 0.5); + + // Compute log(1 + Mag) + cvAddS(image_Re, cvScalarAll(1.0), image_Re, NULL); // 1 + Mag + cvLog(image_Re, image_Re); // log(1 + Mag) + + // Rearrange the quadrants of Fourier image so that the origin is at + // the image center + cvShiftDFT(image_Re, image_Re); + + cvReleaseImage(&realInput); + cvReleaseImage(&imaginaryInput); + cvReleaseImage(&complexInput); + cvReleaseImage(&image_Im); + + cvReleaseMat(&dft_A); + + return image_Re; +} + +IplImage* +create_frequency_filtered_image(const IplImage *pImage, int low, int high) +{ + + CvPoint2D32f center; + center.x = (float)(pImage->width / 2); + center.y = (float)(pImage->height / 2); + CvBox2D box; + box.center = center; + + box.size.width = (float)high; + box.size.height = (float)high; + + IplImage *pFilterMask = rb_cvCreateImage(cvGetSize(pImage), IPL_DEPTH_64F, 1); + IplImage *pFiltered = rb_cvCreateImage(cvGetSize(pImage), IPL_DEPTH_64F, 1); + + cvZero(pFilterMask); + cvZero(pFiltered); + + if (high > 0) + cvEllipseBox(pFilterMask, box, cvScalar(255, 255, 255, 255), CV_FILLED, 8, 0); + + box.size.width = (float)low; + box.size.height = (float)low; + if (low > 0) + cvEllipseBox(pFilterMask, box, cvScalar(0, 0, 0, 0), CV_FILLED, 8, 0); + + cvAnd(pImage, pFilterMask, pFiltered, NULL); + + cvReleaseImage(&pFilterMask); + + return pFiltered; +} + +void +high_pass_range(const IplImage *pImage, float lostPercentage, int &outLow, int &outHigh) +{ + if (lostPercentage > 1.0f) { + lostPercentage = 1; + } + else if (lostPercentage < 0.0f) { + lostPercentage = 0; + } + + outHigh = (int)MIN(pImage->width, pImage->height); + outLow = (int)(lostPercentage * outHigh); +} + +/* + * call-seq: + * pyr_segmentation(level, threshold1, threshold2) -> [iplimage, cvseq(include cvconnectedcomp)] + * + * Does image segmentation by pyramids. + * The pyramid builds up to the level level. + * The links between any pixel a on leveli and + * its candidate father pixel b on the adjacent level are established if + * p(c(a),c(b)) < threshold1. After the connected components are defined, they are joined into several clusters. Any two segments A and B belong to the same cluster, if + * p(c(A),c(B)) < threshold2. The input image has only one channel, then + * p(c^2,c^2)=|c^2-c^2|. If the input image has three channels (red, green and blue), then + * p(c^2,c^2)=0,3*(c^2 r-c^2 r)+0.59*(c^2 g-c^2 g)+0,11*(c^2 b-c^2 b) . There may be more than one connected component per a cluster. + * + * Return segmented image and sequence of connected components. + * support single-channel or 3-channel 8bit unsigned image only + */ +VALUE +rb_pyr_segmentation(VALUE self, VALUE level, VALUE threshold1, VALUE threshold2) +{ + IplImage* self_ptr = IPLIMAGE(self); + CvSeq *comp = NULL; + VALUE storage = cCvMemStorage::new_object(); + VALUE dest = Qnil; + try { + dest = cIplImage::new_object(cvGetSize(self_ptr), cvGetElemType(self_ptr)); + cvPyrSegmentation(self_ptr, IPLIMAGE(dest), CVMEMSTORAGE(storage), &comp, + NUM2INT(level), NUM2DBL(threshold1), NUM2DBL(threshold2)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + if (!comp) { + comp = cvCreateSeq(CV_SEQ_CONNECTED_COMP, sizeof(CvSeq), sizeof(CvConnectedComp), CVMEMSTORAGE(storage)); + } + return rb_ary_new3(2, dest, cCvSeq::new_sequence(cCvSeq::rb_class(), comp, cCvConnectedComp::rb_class(), storage)); +} + +VALUE +new_object(int width, int height, int type) +{ + return OPENCV_OBJECT(rb_klass, rb_cvCreateImage(cvSize(width, height), cvIplDepth(type), CV_MAT_CN(type))); +} + +VALUE +new_object(CvSize size, int type) +{ + return OPENCV_OBJECT(rb_klass, rb_cvCreateImage(size, cvIplDepth(type), CV_MAT_CN(type))); +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); + VALUE cvmat = rb_define_class_under(opencv, "CvMat", rb_cObject); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * cvmat = rb_define_class_under(opencv, "CvMat", rb_cObject); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + VALUE cvmat = cCvMat::rb_class(); + rb_klass = rb_define_class_under(opencv, "IplImage", cvmat); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_singleton_method(rb_klass, "load", RUBY_METHOD_FUNC(rb_load_image), -1); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "get_roi", RUBY_METHOD_FUNC(rb_get_roi), 0); + rb_define_alias(rb_klass, "roi", "get_roi"); + rb_define_method(rb_klass, "set_roi", RUBY_METHOD_FUNC(rb_set_roi), 1); + rb_define_alias(rb_klass, "roi=", "set_roi"); + rb_define_method(rb_klass, "reset_roi", RUBY_METHOD_FUNC(rb_reset_roi), 0); + rb_define_method(rb_klass, "get_coi", RUBY_METHOD_FUNC(rb_get_coi), 0); + rb_define_alias(rb_klass, "coi", "get_coi"); + rb_define_method(rb_klass, "set_coi", RUBY_METHOD_FUNC(rb_set_coi), 1); + rb_define_alias(rb_klass, "coi=", "set_coi"); + rb_define_method(rb_klass, "reset_coi", RUBY_METHOD_FUNC(rb_reset_coi), 0); + rb_define_method(rb_klass, "pyr_segmentation", RUBY_METHOD_FUNC(rb_pyr_segmentation), 3); + rb_define_method(rb_klass, "smoothness", RUBY_METHOD_FUNC(rb_smoothness), -1); + + rb_define_singleton_method(rb_klass, "decode_image", RUBY_METHOD_FUNC(rb_decode_image), -1); + rb_define_alias(rb_singleton_class(rb_klass), "decode", "decode_image"); +} + +__NAMESPACE_END_IPLIMAGE +__NAMESPACE_END_OPENCV + diff --git a/ext/iplimage.h b/ext/opencv/iplimage.h similarity index 51% rename from ext/iplimage.h rename to ext/opencv/iplimage.h index 9e7dc081..e7a77f4d 100644 --- a/ext/iplimage.h +++ b/ext/opencv/iplimage.h @@ -12,7 +12,7 @@ #include "opencv.h" -#define __NAMESPACE_BEGIN_IPLIMAGE namespace cIplImage{ +#define __NAMESPACE_BEGIN_IPLIMAGE namespace cIplImage { #define __NAMESPACE_END_IPLIMAGE } __NAMESPACE_BEGIN_OPENCV @@ -20,12 +20,13 @@ __NAMESPACE_BEGIN_IPLIMAGE VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_allocate(VALUE klass); VALUE rb_initialize(int argc, VALUE *argv, VALUE self); VALUE rb_load_image(int argc, VALUE *argv, VALUE self); +VALUE rb_decode_image(int argc, VALUE *argv, VALUE self); VALUE rb_color_model(VALUE self); @@ -37,6 +38,16 @@ VALUE rb_get_coi(VALUE self); VALUE rb_set_coi(VALUE self, VALUE coi); VALUE rb_reset_coi(VALUE self); +VALUE rb_pyr_segmentation(VALUE self, VALUE level, VALUE threshold1, VALUE threshold2); + +VALUE rb_smoothness(int argc, VALUE *argv, VALUE self); +typedef enum { SMOOTH = 1, BLANK = 2, MESSY = 3 } Smoothness; +Smoothness compute_smoothness(const IplImage *pFourierImage, const double lowFreqRatio, const double blankDensity, const double messyDensity, const double highFreqRatio, double &outLowDensity, double &outHighDensity); +void cvShiftDFT(CvArr *src_arr, CvArr *dst_arr ); +IplImage* create_fourier_image(const IplImage *im); +IplImage* create_frequency_filtered_image(const IplImage *pImage, int low, int high); +void high_pass_range(const IplImage *pImage, float lostPercentage, int &outLow, int &outHigh); + VALUE new_object(int width, int height, int type); VALUE new_object(CvSize size, int type); __NAMESPACE_END_IPLIMAGE @@ -49,6 +60,14 @@ IPLIMAGE(VALUE object) return cvGetImage(ptr, &stub); } +inline IplImage* +IPLIMAGE_WITH_CHECK(VALUE object) +{ + if (!rb_obj_is_kind_of(object, cIplImage::rb_class())) + raise_typeerror(object, cIplImage::rb_class()); + return IPLIMAGE(object); +} + __NAMESPACE_END_OPENCV #endif // RUBY_OPENCV_IPLIMAGE_H diff --git a/ext/opencv/lbph.cpp b/ext/opencv/lbph.cpp new file mode 100644 index 00000000..895fe32a --- /dev/null +++ b/ext/opencv/lbph.cpp @@ -0,0 +1,78 @@ +/************************************************************ + + lbph.cpp - + + $Author: ser1zw $ + + Copyright (C) 2013 ser1zw + +************************************************************/ +#include +#include "lbph.h" +/* + * Document-class: OpenCV::LBPH + * + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_LBPH + +VALUE rb_klass; + +VALUE +rb_class() +{ + return rb_klass; +} + +/* + * call-seq: + * LBPH.new(radius=1, neighbors=8, grid_x=8, grid_y=8, threshold=DBL_MAX) -> cvmat + */ +VALUE +rb_initialize(int argc, VALUE argv[], VALUE self) +{ + VALUE radius_val, neighbors_val, grid_x_val, grid_y_val, threshold_val; + rb_scan_args(argc, argv, "05", &radius_val, &neighbors_val, &grid_x_val, &grid_y_val, &threshold_val); + + int radius = NIL_P(radius_val) ? 1 : NUM2INT(radius_val); + int neighbors = NIL_P(neighbors_val) ? 8 : NUM2INT(neighbors_val); + int grid_x = NIL_P(grid_x_val) ? 8 : NUM2INT(grid_x_val); + int grid_y = NIL_P(grid_y_val) ? 8 : NUM2INT(grid_y_val); + double threshold = NIL_P(threshold_val) ? DBL_MAX : NUM2INT(threshold_val); + + free(DATA_PTR(self)); + cv::Ptr ptr = cv::createLBPHFaceRecognizer(radius, neighbors, grid_x, grid_y, threshold); + DATA_PTR(self) = ptr; + + cFaceRecognizer::guard_facerecognizer(DATA_PTR(self), ptr); + + return self; +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); + VALUE alghorithm = rb_define_class_under(opencv, "Algorithm", rb_cObject); + VALUE face_recognizer = rb_define_class_under(opencv, "FaceRecognizer", alghorithm); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + VALUE face_recognizer = cFaceRecognizer::rb_class(); + rb_klass = rb_define_class_under(opencv, "LBPH", face_recognizer); + rb_define_alloc_func(rb_klass, cFaceRecognizer::allocate_facerecognizer); + rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); +} + +__NAMESPACE_END_LBPH +__NAMESPACE_END_OPENCV + diff --git a/ext/opencv/lbph.h b/ext/opencv/lbph.h new file mode 100644 index 00000000..2903af53 --- /dev/null +++ b/ext/opencv/lbph.h @@ -0,0 +1,30 @@ +/************************************************************ + + lbph.h + + $Author: ser1zw $ + + Copyright (C) 2013 ser1zw + +************************************************************/ +#ifndef RUBY_OPENCV_LBPH_H +#define RUBY_OPENCV_LBPH_H + +#include "opencv.h" + +#define __NAMESPACE_BEGIN_LBPH namespace cLBPH { +#define __NAMESPACE_END_LBPH } + +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_LBPH + +VALUE rb_class(); + +void init_ruby_class(); +VALUE rb_initialize(int argc, VALUE argv[], VALUE self); + +__NAMESPACE_END_LBPH +__NAMESPACE_END_OPENCV + +#endif // RUBY_OPENCV_LBPH_H + diff --git a/ext/mouseevent.cpp b/ext/opencv/mouseevent.cpp similarity index 83% rename from ext/mouseevent.cpp rename to ext/opencv/mouseevent.cpp index 615902c6..4b40936c 100644 --- a/ext/mouseevent.cpp +++ b/ext/opencv/mouseevent.cpp @@ -7,15 +7,11 @@ Copyright (C) 2005-2007 Masakazu Yonekura ************************************************************/ -#ifdef HAVE_CALLBACK_H - #include "mouseevent.h" /* * Document-module: OpenCV::GUI::MouseEvent * * MouseEvent object. - * have - * see OpenCV::GUI::Window#set_mouse_callback. */ __NAMESPACE_BEGIN_OPENCV __NAMESPACE_BEGIN_GUI @@ -29,34 +25,11 @@ rb_class() return rb_klass; } -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * GUI = rb_define_module_under(opencv, "GUI"); - * cvpoint = rb_define_class_under(opencv, "CvPoint", rb_cObject); - */ - VALUE GUI = rb_module_GUI(); - VALUE cvpoint = cCvPoint::rb_class(); - rb_klass = rb_define_class_under(GUI, "MouseEvent", cvpoint); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_method(rb_klass, "event", RUBY_METHOD_FUNC(rb_event), 0); - rb_define_method(rb_klass, "left_button?", RUBY_METHOD_FUNC(rb_left_button_q), 0); - rb_define_method(rb_klass, "right_button?", RUBY_METHOD_FUNC(rb_right_button_q), 0); - rb_define_method(rb_klass, "middle_button?", RUBY_METHOD_FUNC(rb_middle_button_q), 0); - rb_define_method(rb_klass, "ctrl_key?", RUBY_METHOD_FUNC(rb_ctrl_key_q), 0); - rb_define_method(rb_klass, "shift_key?", RUBY_METHOD_FUNC(rb_shift_key_q), 0); - rb_define_method(rb_klass, "alt_key?", RUBY_METHOD_FUNC(rb_alt_key_q), 0); -} - VALUE rb_allocate(VALUE klass) { MouseEvent *ptr; - return Data_Make_Struct(klass, MouseEvent, 0, -1, ptr); + return Data_Make_Struct(klass, MouseEvent, 0, 0, ptr); } /* @@ -117,7 +90,7 @@ VALUE rb_event(VALUE self) VALUE rb_left_button_q(VALUE self) { - return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_LBUTTON ? Qtrue : Qfalse; + return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_LBUTTON ? Qtrue : Qfalse; } /* @@ -126,7 +99,7 @@ rb_left_button_q(VALUE self) VALUE rb_right_button_q(VALUE self) { - return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_RBUTTON ? Qtrue : Qfalse; + return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_RBUTTON ? Qtrue : Qfalse; } /* @@ -135,7 +108,7 @@ rb_right_button_q(VALUE self) VALUE rb_middle_button_q(VALUE self) { - return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_MBUTTON ? Qtrue : Qfalse; + return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_MBUTTON ? Qtrue : Qfalse; } /* @@ -144,7 +117,7 @@ rb_middle_button_q(VALUE self) VALUE rb_ctrl_key_q(VALUE self) { - return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_CTRLKEY ? Qtrue : Qfalse; + return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_CTRLKEY ? Qtrue : Qfalse; } /* @@ -153,7 +126,7 @@ rb_ctrl_key_q(VALUE self) VALUE rb_shift_key_q(VALUE self) { - return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_SHIFTKEY ? Qtrue : Qfalse; + return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_SHIFTKEY ? Qtrue : Qfalse; } /* @@ -162,23 +135,52 @@ rb_shift_key_q(VALUE self) VALUE rb_alt_key_q(VALUE self) { - return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_ALTKEY ? Qtrue : Qfalse; + return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_ALTKEY ? Qtrue : Qfalse; } VALUE -new_object(int flag, int y, int x, int event) +new_object(int event, int x, int y, int flags) { VALUE object = rb_allocate(rb_class()); MouseEvent *mouseevent = MOUSEEVENT(object); mouseevent->point.x = x; mouseevent->point.y = y; mouseevent->event = event; - mouseevent->flag = flag; + mouseevent->flags = flags; return object; } +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); + VALUE GUI = rb_define_module_under(opencv, "GUI"); + VALUE cvpoint = rb_define_class_under(opencv, "CvPoint", rb_cObject); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * GUI = rb_define_module_under(opencv, "GUI"); + * cvpoint = rb_define_class_under(opencv, "CvPoint", rb_cObject); + */ + VALUE GUI = rb_module_GUI(); + VALUE cvpoint = cCvPoint::rb_class(); + rb_klass = rb_define_class_under(GUI, "MouseEvent", cvpoint); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_method(rb_klass, "event", RUBY_METHOD_FUNC(rb_event), 0); + rb_define_method(rb_klass, "left_button?", RUBY_METHOD_FUNC(rb_left_button_q), 0); + rb_define_method(rb_klass, "right_button?", RUBY_METHOD_FUNC(rb_right_button_q), 0); + rb_define_method(rb_klass, "middle_button?", RUBY_METHOD_FUNC(rb_middle_button_q), 0); + rb_define_method(rb_klass, "ctrl_key?", RUBY_METHOD_FUNC(rb_ctrl_key_q), 0); + rb_define_method(rb_klass, "shift_key?", RUBY_METHOD_FUNC(rb_shift_key_q), 0); + rb_define_method(rb_klass, "alt_key?", RUBY_METHOD_FUNC(rb_alt_key_q), 0); +} + __NAMESPACE_END_MOUSEEVENT __NAMESPACE_END_GUI __NAMESPACE_END_OPENCV -#endif // HAVE_CALLBACK_H diff --git a/ext/mouseevent.h b/ext/opencv/mouseevent.h similarity index 79% rename from ext/mouseevent.h rename to ext/opencv/mouseevent.h index a74f99db..8ad49484 100644 --- a/ext/mouseevent.h +++ b/ext/opencv/mouseevent.h @@ -7,29 +7,27 @@ Copyright (C) 2005-2006 Masakazu Yonekura ************************************************************/ -#ifdef HAVE_CALLBACK_H - -#define __NAMESPACE_BEGIN_MOUSEEVENT namespace cMouseEvent{ +#define __NAMESPACE_BEGIN_MOUSEEVENT namespace cMouseEvent { #define __NAMESPACE_END_MOUSEEVENT } #ifndef RUBY_OPENCV_GUI_MOUSEEVENT_H #define RUBY_OPENCV_GUI_MOUSEEVENT_H -#include"opencv.h" +#include "opencv.h" __NAMESPACE_BEGIN_OPENCV __NAMESPACE_BEGIN_GUI __NAMESPACE_BEGIN_MOUSEEVENT -typedef struct MouseEvent{ +typedef struct MouseEvent { CvPoint point; int event; - int flag; -}MouseEvent; + int flags; +} MouseEvent; VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_allocate(VALUE klass); @@ -44,7 +42,7 @@ VALUE rb_alt_key_q(VALUE self); VALUE new_object(int event, int x, int y, int flag); -inline MouseEvent *MOUSEEVENT(VALUE object){ +inline MouseEvent *MOUSEEVENT(VALUE object) { MouseEvent *ptr; Data_Get_Struct(object, MouseEvent, ptr); return ptr; @@ -56,4 +54,3 @@ __NAMESPACE_END_OPENCV #endif // RUBY_OPENCV_GUI_MOUSEEVENT_H -#endif // HAVE_CALLBACK_H diff --git a/ext/opencv/opencv.cpp b/ext/opencv/opencv.cpp new file mode 100644 index 00000000..e02bbdb0 --- /dev/null +++ b/ext/opencv/opencv.cpp @@ -0,0 +1,819 @@ +/************************************************************ + + opencv.cpp - + + $Author: lsxi $ + + Copyright (C) 2005-2008 Masakazu Yonekura + +************************************************************/ +/* + * Document-module: OpenCV + * + * =What is OpenCV? + * + * OpenCV is "Open Source Computer Vision Library". + * OpenCV is developed by Intel and many opensource developers. + * This library include many useful function for computer vision, such as object-detection. + * + * OpenCV is developed at + * sourceforge.net[http://sourceforge.net/projects/opencvlibrary] + * + * =What is Ruby/OpenCV? + * Ruby/OpenCV is manual Wrapper of OpenCV (not use SWIG). + * This library seem to be *Ruby*. + * * object-oriented + * * support Garbage Collection by Ruby + * Ruby/OpenCV is developed + * http://rubyforge.org/projects/opencv (Official) + * and + * http://blueruby.mydns.jp/pages/opencv (Japanese) + * + * =How to install + * + * Show INSTALL + * + * =How to generate this documentation? + * This document created by rdoc. + * If you have Ruby 1.8 or later, you might use rdoc command. + * for example + * > cd opencv + * > rdoc + * and show "./doc/index.html" + */ +#include "opencv.h" + +__NAMESPACE_BEGIN_OPENCV + + +/* + * Hashtable for protect from GC + */ +st_table *root_table = st_init_numtable(); + +/* + * Mark root object. (protect from GC) + */ +void +mark_root_object(void *ptr) +{ + VALUE value; + if (ptr && st_lookup(root_table, (st_data_t)ptr, (st_data_t*)&value)) { + rb_gc_mark(value); + } +} + +/* + * Look-up Root root object. + */ +VALUE +lookup_root_object(void *ptr) +{ + VALUE value = 0; + if (ptr) + st_lookup(root_table, (st_data_t)ptr, (st_data_t*)&value); + return value; +} + +/* + * Register root object. + */ +void +register_root_object(void *ptr, VALUE root) +{ + st_insert(root_table, (st_data_t)ptr, (st_data_t)root); +} + +/* + * Delete mark symbol from hashtable only, not free memory. + */ +void +unregister_object(void *ptr) +{ + st_delete(root_table, (st_data_t*)&ptr, 0); +} + +/* + * Delete mark symbol from hash table, then free memory. + */ +void +free_object(void *ptr) +{ + if (ptr) { + unregister_object(ptr); + try { + cvFree(&ptr); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + } +} + +/* + * Release OpenCV specific structure(i.e CvMat, IplImage..) from memory and delete from hashtable. + */ +void +release_object(void *ptr) +{ + if (ptr) { + unregister_object(ptr); + try { + cvRelease(&ptr); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + } +} + +/* + * Release IplConvKernel object from memory and delete from hashtable. + */ +void +release_iplconvkernel_object(void *ptr) +{ + if (ptr) { + unregister_object(ptr); + try { + cvReleaseStructuringElement((IplConvKernel**)(&ptr)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + } +} + +VALUE rb_module; +VALUE rb_opencv_constants; + +VALUE +rb_module_opencv() +{ + return rb_module; +} + +void +init_ruby_module() +{ + if (rb_module) + return; + rb_module = rb_define_module("OpenCV"); + + /* OpenCV version */ + rb_define_const(rb_module, "CV_VERSION", rb_str_new2(CV_VERSION)); + rb_define_const(rb_module, "CV_MAJOR_VERSION", INT2FIX(CV_MAJOR_VERSION)); + rb_define_const(rb_module, "CV_MINOR_VERSION", INT2FIX(CV_MINOR_VERSION)); + rb_define_const(rb_module, "CV_SUBMINOR_VERSION", INT2FIX(CV_SUBMINOR_VERSION)); + + rb_define_const(rb_module, "CV_VERSION_EPOCH", INT2FIX(CV_VERSION_EPOCH)); + rb_define_const(rb_module, "CV_VERSION_MAJOR", INT2FIX(CV_VERSION_MAJOR)); + rb_define_const(rb_module, "CV_VERSION_MINOR", INT2FIX(CV_VERSION_MINOR)); + rb_define_const(rb_module, "CV_VERSION_REVISION", INT2FIX(CV_VERSION_REVISION)); + + /* 0: 8bit unsigned */ + rb_define_const(rb_module, "CV_8U", INT2FIX(CV_8U)); + /* 1: 8bit signed */ + rb_define_const(rb_module, "CV_8S", INT2FIX(CV_8S)); + /* 2: 16bit unsigned */ + rb_define_const(rb_module, "CV_16U", INT2FIX(CV_16U)); + /* 3: 16bit signed */ + rb_define_const(rb_module, "CV_16S", INT2FIX(CV_16S)); + /* 4: 32bit signed */ + rb_define_const(rb_module, "CV_32S", INT2FIX(CV_32S)); + /* 5: 32bit floating-point */ + rb_define_const(rb_module, "CV_32F", INT2FIX(CV_32F)); + /* 6: 64bit floating-point */ + rb_define_const(rb_module, "CV_64F", INT2FIX(CV_64F)); + + /* Other depth */ + rb_define_const(rb_module, "CV_8UC1", INT2FIX(CV_8UC1)); + rb_define_const(rb_module, "CV_8UC2", INT2FIX(CV_8UC2)); + rb_define_const(rb_module, "CV_8UC3", INT2FIX(CV_8UC3)); + rb_define_const(rb_module, "CV_8UC4", INT2FIX(CV_8UC4)); + rb_define_const(rb_module, "CV_8SC1", INT2FIX(CV_8SC1)); + rb_define_const(rb_module, "CV_8SC2", INT2FIX(CV_8SC2)); + rb_define_const(rb_module, "CV_8SC3", INT2FIX(CV_8SC3)); + rb_define_const(rb_module, "CV_8SC4", INT2FIX(CV_8SC4)); + rb_define_const(rb_module, "CV_16UC1", INT2FIX(CV_16UC1)); + rb_define_const(rb_module, "CV_16UC2", INT2FIX(CV_16UC2)); + rb_define_const(rb_module, "CV_16UC3", INT2FIX(CV_16UC3)); + rb_define_const(rb_module, "CV_16UC4", INT2FIX(CV_16UC4)); + rb_define_const(rb_module, "CV_16SC1", INT2FIX(CV_16SC1)); + rb_define_const(rb_module, "CV_16SC2", INT2FIX(CV_16SC2)); + rb_define_const(rb_module, "CV_16SC3", INT2FIX(CV_16SC3)); + rb_define_const(rb_module, "CV_16SC4", INT2FIX(CV_16SC4)); + rb_define_const(rb_module, "CV_32SC1", INT2FIX(CV_32SC1)); + rb_define_const(rb_module, "CV_32SC2", INT2FIX(CV_32SC2)); + rb_define_const(rb_module, "CV_32SC3", INT2FIX(CV_32SC3)); + rb_define_const(rb_module, "CV_32SC4", INT2FIX(CV_32SC4)); + rb_define_const(rb_module, "CV_32FC1", INT2FIX(CV_32FC1)); + rb_define_const(rb_module, "CV_32FC2", INT2FIX(CV_32FC2)); + rb_define_const(rb_module, "CV_32FC3", INT2FIX(CV_32FC3)); + rb_define_const(rb_module, "CV_32FC4", INT2FIX(CV_32FC4)); + rb_define_const(rb_module, "CV_64FC1", INT2FIX(CV_64FC1)); + rb_define_const(rb_module, "CV_64FC2", INT2FIX(CV_64FC2)); + rb_define_const(rb_module, "CV_64FC3", INT2FIX(CV_64FC3)); + rb_define_const(rb_module, "CV_64FC4", INT2FIX(CV_64FC4)); + + /* Color types of loaded images */ + rb_define_const(rb_module, "CV_LOAD_IMAGE_UNCHANGED", INT2FIX(CV_LOAD_IMAGE_UNCHANGED)); + rb_define_const(rb_module, "CV_LOAD_IMAGE_GRAYSCALE", INT2FIX(CV_LOAD_IMAGE_GRAYSCALE)); + rb_define_const(rb_module, "CV_LOAD_IMAGE_COLOR", INT2FIX(CV_LOAD_IMAGE_COLOR)); + rb_define_const(rb_module, "CV_LOAD_IMAGE_ANYDEPTH", INT2FIX(CV_LOAD_IMAGE_ANYDEPTH)); + rb_define_const(rb_module, "CV_LOAD_IMAGE_ANYCOLOR", INT2FIX(CV_LOAD_IMAGE_ANYCOLOR)); + + /* Format-specific save parameters */ + rb_define_const(rb_module, "CV_IMWRITE_JPEG_QUALITY", INT2FIX(CV_IMWRITE_JPEG_QUALITY)); + rb_define_const(rb_module, "CV_IMWRITE_PNG_COMPRESSION", INT2FIX(CV_IMWRITE_PNG_COMPRESSION)); + rb_define_const(rb_module, "CV_IMWRITE_PNG_STRATEGY", INT2FIX(CV_IMWRITE_PNG_STRATEGY)); + rb_define_const(rb_module, "CV_IMWRITE_PNG_STRATEGY_DEFAULT", INT2FIX(CV_IMWRITE_PNG_STRATEGY_DEFAULT)); + rb_define_const(rb_module, "CV_IMWRITE_PNG_STRATEGY_FILTERED", INT2FIX(CV_IMWRITE_PNG_STRATEGY_FILTERED)); + rb_define_const(rb_module, "CV_IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY", INT2FIX(CV_IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY)); + rb_define_const(rb_module, "CV_IMWRITE_PNG_STRATEGY_RLE", INT2FIX(CV_IMWRITE_PNG_STRATEGY_RLE)); + rb_define_const(rb_module, "CV_IMWRITE_PNG_STRATEGY_FIXED", INT2FIX(CV_IMWRITE_PNG_STRATEGY_FIXED)); + rb_define_const(rb_module, "CV_IMWRITE_PXM_BINARY", INT2FIX(CV_IMWRITE_PXM_BINARY)); + + /* Types of morphological operations */ + rb_define_const(rb_module, "CV_MOP_OPEN", INT2FIX(CV_MOP_OPEN)); + rb_define_const(rb_module, "CV_MOP_CLOSE", INT2FIX(CV_MOP_CLOSE)); + rb_define_const(rb_module, "CV_MOP_GRADIENT", INT2FIX(CV_MOP_GRADIENT)); + rb_define_const(rb_module, "CV_MOP_TOPHAT", INT2FIX(CV_MOP_TOPHAT)); + rb_define_const(rb_module, "CV_MOP_BLACKHAT", INT2FIX(CV_MOP_BLACKHAT)); + + /* Shape of the structuring elements */ + rb_define_const(rb_module, "CV_SHAPE_RECT", INT2FIX(CV_SHAPE_RECT)); + rb_define_const(rb_module, "CV_SHAPE_CROSS", INT2FIX(CV_SHAPE_CROSS)); + rb_define_const(rb_module, "CV_SHAPE_ELLIPSE", INT2FIX(CV_SHAPE_ELLIPSE)); + rb_define_const(rb_module, "CV_SHAPE_CUSTOM", INT2FIX(CV_SHAPE_CUSTOM)); + + /* Types of the smoothing */ + rb_define_const(rb_module, "CV_BLUR_NO_SCALE", INT2FIX(CV_BLUR_NO_SCALE)); + rb_define_const(rb_module, "CV_BLUR", INT2FIX(CV_BLUR)); + rb_define_const(rb_module, "CV_GAUSSIAN", INT2FIX(CV_GAUSSIAN)); + rb_define_const(rb_module, "CV_MEDIAN", INT2FIX(CV_MEDIAN)); + rb_define_const(rb_module, "CV_BILATERAL", INT2FIX(CV_BILATERAL)); + + /* Thresholding types */ + rb_define_const(rb_module, "CV_THRESH_BINARY", INT2FIX(CV_THRESH_BINARY)); + rb_define_const(rb_module, "CV_THRESH_BINARY_INV", INT2FIX(CV_THRESH_BINARY_INV)); + rb_define_const(rb_module, "CV_THRESH_TRUNC", INT2FIX(CV_THRESH_TRUNC)); + rb_define_const(rb_module, "CV_THRESH_TOZERO", INT2FIX(CV_THRESH_TOZERO)); + rb_define_const(rb_module, "CV_THRESH_TOZERO_INV", INT2FIX(CV_THRESH_TOZERO_INV)); + rb_define_const(rb_module, "CV_THRESH_OTSU", INT2FIX(CV_THRESH_OTSU)); + + /* Adaptive methods */ + rb_define_const(rb_module, "CV_ADAPTIVE_THRESH_MEAN_C", INT2FIX(CV_ADAPTIVE_THRESH_MEAN_C)); + rb_define_const(rb_module, "CV_ADAPTIVE_THRESH_GAUSSIAN_C", INT2FIX(CV_ADAPTIVE_THRESH_GAUSSIAN_C)); + + /* Border type */ + rb_define_const(rb_module, "IPL_BORDER_CONSTANT", INT2FIX(IPL_BORDER_CONSTANT)); + rb_define_const(rb_module, "IPL_BORDER_REPLICATE", INT2FIX(IPL_BORDER_REPLICATE)); + + /* Retrieval mode */ + rb_define_const(rb_module, "CV_RETR_EXTERNAL", INT2FIX(CV_RETR_EXTERNAL)); + rb_define_const(rb_module, "CV_RETR_LIST", INT2FIX(CV_RETR_LIST)); + rb_define_const(rb_module, "CV_RETR_CCOMP", INT2FIX(CV_RETR_CCOMP)); + rb_define_const(rb_module, "CV_RETR_TREE", INT2FIX(CV_RETR_TREE)); + + /* Approximation method */ + rb_define_const(rb_module, "CV_CHAIN_CODE", INT2FIX(CV_CHAIN_CODE)); + rb_define_const(rb_module, "CV_CHAIN_APPROX_NONE", INT2FIX(CV_CHAIN_APPROX_NONE)); + rb_define_const(rb_module, "CV_CHAIN_APPROX_SIMPLE", INT2FIX(CV_CHAIN_APPROX_SIMPLE)); + rb_define_const(rb_module, "CV_CHAIN_APPROX_TC89_L1", INT2FIX(CV_CHAIN_APPROX_TC89_L1)); + rb_define_const(rb_module, "CV_CHAIN_APPROX_TC89_KCOS", INT2FIX(CV_CHAIN_APPROX_TC89_KCOS)); + rb_define_const(rb_module, "CV_LINK_RUNS", INT2FIX(CV_LINK_RUNS)); + + /* Termination criteria for iterative algorithms */ + rb_define_const(rb_module, "CV_TERMCRIT_ITER", INT2FIX(CV_TERMCRIT_ITER)); + rb_define_const(rb_module, "CV_TERMCRIT_NUMBER", INT2FIX(CV_TERMCRIT_NUMBER)); + rb_define_const(rb_module, "CV_TERMCRIT_EPS", INT2FIX(CV_TERMCRIT_EPS)); + + /* Hough transform method */ + rb_define_const(rb_module, "CV_HOUGH_STANDARD", INT2FIX(CV_HOUGH_STANDARD)); + rb_define_const(rb_module, "CV_HOUGH_PROBABILISTIC", INT2FIX(CV_HOUGH_PROBABILISTIC)); + rb_define_const(rb_module, "CV_HOUGH_MULTI_SCALE", INT2FIX(CV_HOUGH_MULTI_SCALE)); + rb_define_const(rb_module, "CV_HOUGH_GRADIENT", INT2FIX(CV_HOUGH_GRADIENT)); + + /* Inpaint method */ + rb_define_const(rb_module, "CV_INPAINT_NS", INT2FIX(CV_INPAINT_NS)); + rb_define_const(rb_module, "CV_INPAINT_TELEA", INT2FIX(CV_INPAINT_TELEA)); + + /* Match template method */ + rb_define_const(rb_module, "CV_TM_SQDIFF", INT2FIX(CV_TM_SQDIFF)); + rb_define_const(rb_module, "CV_TM_SQDIFF_NORMED", INT2FIX(CV_TM_SQDIFF_NORMED)); + rb_define_const(rb_module, "CV_TM_CCORR", INT2FIX(CV_TM_CCORR)); + rb_define_const(rb_module, "CV_TM_CCORR_NORMED", INT2FIX(CV_TM_CCORR_NORMED)); + rb_define_const(rb_module, "CV_TM_CCOEFF", INT2FIX(CV_TM_CCOEFF)); + rb_define_const(rb_module, "CV_TM_CCOEFF_NORMED", INT2FIX(CV_TM_CCOEFF_NORMED)); + + /* Comparison method */ + rb_define_const(rb_module, "CV_CONTOURS_MATCH_I1", INT2FIX(CV_CONTOURS_MATCH_I1)); + rb_define_const(rb_module, "CV_CONTOURS_MATCH_I2", INT2FIX(CV_CONTOURS_MATCH_I2)); + rb_define_const(rb_module, "CV_CONTOURS_MATCH_I3", INT2FIX(CV_CONTOURS_MATCH_I3)); + + /* Fundamental matrix computing methods */ + rb_define_const(rb_module, "CV_FM_7POINT", INT2FIX(CV_FM_7POINT)); + rb_define_const(rb_module, "CV_FM_8POINT", INT2FIX(CV_FM_8POINT)); + rb_define_const(rb_module, "CV_FM_RANSAC", INT2FIX(CV_FM_RANSAC)); + rb_define_const(rb_module, "CV_FM_LMEDS", INT2FIX(CV_FM_LMEDS)); + + /* Flags of window */ + rb_define_const(rb_module, "CV_WINDOW_AUTOSIZE", INT2FIX(CV_WINDOW_AUTOSIZE)); + rb_define_const(rb_module, "CV_WINDOW_NORMAL", INT2FIX(CV_WINDOW_NORMAL)); + rb_define_const(rb_module, "CV_WINDOW_OPENGL", INT2FIX(CV_WINDOW_OPENGL)); + + /* Object detection mode */ + rb_define_const(rb_module, "CV_HAAR_DO_CANNY_PRUNING", INT2FIX(CV_HAAR_DO_CANNY_PRUNING)); + + /* Interpolation methods */ + rb_define_const(rb_module, "CV_INTER_NN", INT2FIX(CV_INTER_NN)); + rb_define_const(rb_module, "CV_INTER_LINEAR", INT2FIX(CV_INTER_LINEAR)); + rb_define_const(rb_module, "CV_INTER_AREA", INT2FIX(CV_INTER_AREA)); + rb_define_const(rb_module, "CV_INTER_CUBIC", INT2FIX(CV_INTER_CUBIC)); + rb_define_const(rb_module, "CV_INTER_LANCZOS4", INT2FIX(CV_INTER_LANCZOS4)); + + /* Warp affine optional flags */ + rb_define_const(rb_module, "CV_WARP_FILL_OUTLIERS", INT2FIX(CV_WARP_FILL_OUTLIERS)); + rb_define_const(rb_module, "CV_WARP_INVERSE_MAP", INT2FIX(CV_WARP_INVERSE_MAP)); + + /* SVD optional flags */ + rb_define_const(rb_module, "CV_SVD_MODIFY_A", INT2FIX(CV_SVD_MODIFY_A)); + rb_define_const(rb_module, "CV_SVD_U_T", INT2FIX(CV_SVD_U_T)); + rb_define_const(rb_module, "CV_SVD_V_T", INT2FIX(CV_SVD_V_T)); + + /* Norm types */ + rb_define_const(rb_module, "CV_NORM_INF", INT2FIX(cv::NORM_INF)); + rb_define_const(rb_module, "CV_NORM_L1", INT2FIX(cv::NORM_L1)); + rb_define_const(rb_module, "CV_NORM_L2", INT2FIX(cv::NORM_L2)); + rb_define_const(rb_module, "CV_NORM_MINMAX", INT2FIX(cv::NORM_MINMAX)); + + /* Histogram representation format */ + rb_define_const(rb_module, "CV_HIST_ARRAY", INT2FIX(CV_HIST_ARRAY)); + rb_define_const(rb_module, "CV_HIST_SPARSE", INT2FIX(CV_HIST_SPARSE)); + rb_define_const(rb_module, "CV_HIST_TREE", INT2FIX(CV_HIST_TREE)); + rb_define_const(rb_module, "CV_HIST_UNIFORM", INT2FIX(CV_HIST_UNIFORM)); + + /* Histogram comparison method */ + rb_define_const(rb_module, "CV_COMP_CORREL", INT2FIX(CV_COMP_CORREL)); + rb_define_const(rb_module, "CV_COMP_CHISQR", INT2FIX(CV_COMP_CHISQR)); + rb_define_const(rb_module, "CV_COMP_INTERSECT", INT2FIX(CV_COMP_INTERSECT)); + rb_define_const(rb_module, "CV_COMP_BHATTACHARYYA", INT2FIX(CV_COMP_BHATTACHARYYA)); + + /* DFT and DCT flags */ + rb_define_const(rb_module, "CV_DXT_FORWARD", INT2FIX(CV_DXT_FORWARD)); + rb_define_const(rb_module, "CV_DXT_INVERSE", INT2FIX(CV_DXT_INVERSE)); + rb_define_const(rb_module, "CV_DXT_SCALE", INT2FIX(CV_DXT_SCALE)); + rb_define_const(rb_module, "CV_DXT_INV_SCALE", INT2FIX(CV_DXT_INV_SCALE)); + rb_define_const(rb_module, "CV_DXT_INVERSE_SCALE", INT2FIX(CV_DXT_INVERSE_SCALE)); + rb_define_const(rb_module, "CV_DXT_ROWS", INT2FIX(CV_DXT_ROWS)); + + /* FindChessboardCorners flags */ + rb_define_const(rb_module, "CV_CALIB_CB_ADAPTIVE_THRESH", INT2FIX(CV_CALIB_CB_ADAPTIVE_THRESH)); + rb_define_const(rb_module, "CV_CALIB_CB_NORMALIZE_IMAGE", INT2FIX(CV_CALIB_CB_NORMALIZE_IMAGE)); + rb_define_const(rb_module, "CV_CALIB_CB_FILTER_QUADS", INT2FIX(CV_CALIB_CB_FILTER_QUADS)); + rb_define_const(rb_module, "CV_CALIB_CB_FAST_CHECK", INT2FIX(CV_CALIB_CB_FAST_CHECK)); + + /* Color map for cv::applyColorMap */ + rb_define_const(rb_module, "COLORMAP_AUTUMN", INT2FIX(cv::COLORMAP_AUTUMN)); + rb_define_const(rb_module, "COLORMAP_BONE", INT2FIX(cv::COLORMAP_BONE)); + rb_define_const(rb_module, "COLORMAP_JET", INT2FIX(cv::COLORMAP_JET)); + rb_define_const(rb_module, "COLORMAP_WINTER", INT2FIX(cv::COLORMAP_WINTER)); + rb_define_const(rb_module, "COLORMAP_RAINBOW", INT2FIX(cv::COLORMAP_RAINBOW)); + rb_define_const(rb_module, "COLORMAP_OCEAN", INT2FIX(cv::COLORMAP_OCEAN)); + rb_define_const(rb_module, "COLORMAP_SUMMER", INT2FIX(cv::COLORMAP_SUMMER)); + rb_define_const(rb_module, "COLORMAP_SPRING", INT2FIX(cv::COLORMAP_SPRING)); + rb_define_const(rb_module, "COLORMAP_COOL", INT2FIX(cv::COLORMAP_COOL)); + rb_define_const(rb_module, "COLORMAP_HSV", INT2FIX(cv::COLORMAP_HSV)); + rb_define_const(rb_module, "COLORMAP_PINK", INT2FIX(cv::COLORMAP_PINK)); + rb_define_const(rb_module, "COLORMAP_HOT", INT2FIX(cv::COLORMAP_HOT)); + + /* Sequence types */ + rb_define_const(rb_module, "CV_SEQ_ELTYPE_BITS", INT2FIX(CV_SEQ_ELTYPE_BITS)); + rb_define_const(rb_module, "CV_SEQ_ELTYPE_MASK", INT2FIX(CV_SEQ_ELTYPE_MASK)); + rb_define_const(rb_module, "CV_SEQ_ELTYPE_POINT", INT2FIX(CV_SEQ_ELTYPE_POINT)); + rb_define_const(rb_module, "CV_SEQ_ELTYPE_CODE", INT2FIX(CV_SEQ_ELTYPE_CODE)); + rb_define_const(rb_module, "CV_SEQ_ELTYPE_GENERIC", INT2FIX(CV_SEQ_ELTYPE_GENERIC)); + rb_define_const(rb_module, "CV_SEQ_ELTYPE_PTR", INT2FIX(CV_SEQ_ELTYPE_PTR)); + rb_define_const(rb_module, "CV_SEQ_ELTYPE_PPOINT", INT2FIX(CV_SEQ_ELTYPE_PPOINT)); + rb_define_const(rb_module, "CV_SEQ_ELTYPE_INDEX", INT2FIX(CV_SEQ_ELTYPE_INDEX)); + rb_define_const(rb_module, "CV_SEQ_ELTYPE_GRAPH_EDGE", INT2FIX(CV_SEQ_ELTYPE_GRAPH_EDGE)); + rb_define_const(rb_module, "CV_SEQ_ELTYPE_GRAPH_VERTEX", INT2FIX(CV_SEQ_ELTYPE_GRAPH_VERTEX)); + rb_define_const(rb_module, "CV_SEQ_ELTYPE_TRIAN_ATR", INT2FIX(CV_SEQ_ELTYPE_TRIAN_ATR)); + rb_define_const(rb_module, "CV_SEQ_ELTYPE_CONNECTED_COMP", INT2FIX(CV_SEQ_ELTYPE_CONNECTED_COMP)); + rb_define_const(rb_module, "CV_SEQ_ELTYPE_POINT3D", INT2FIX(CV_SEQ_ELTYPE_POINT3D)); + rb_define_const(rb_module, "CV_SEQ_KIND_BITS", INT2FIX(CV_SEQ_KIND_BITS)); + rb_define_const(rb_module, "CV_SEQ_KIND_MASK", INT2FIX(CV_SEQ_KIND_MASK)); + rb_define_const(rb_module, "CV_SEQ_KIND_GENERIC", INT2FIX(CV_SEQ_KIND_GENERIC)); + rb_define_const(rb_module, "CV_SEQ_KIND_CURVE", INT2FIX(CV_SEQ_KIND_CURVE)); + rb_define_const(rb_module, "CV_SEQ_KIND_BIN_TREE", INT2FIX(CV_SEQ_KIND_BIN_TREE)); + rb_define_const(rb_module, "CV_SEQ_KIND_GRAPH", INT2FIX(CV_SEQ_KIND_GRAPH)); + rb_define_const(rb_module, "CV_SEQ_KIND_SUBDIV2D", INT2FIX(CV_SEQ_KIND_SUBDIV2D)); + rb_define_const(rb_module, "CV_SEQ_FLAG_SHIFT", INT2FIX(CV_SEQ_FLAG_SHIFT)); + rb_define_const(rb_module, "CV_SEQ_FLAG_CLOSED", INT2FIX(CV_SEQ_FLAG_CLOSED)); + rb_define_const(rb_module, "CV_SEQ_FLAG_SIMPLE", INT2FIX(CV_SEQ_FLAG_SIMPLE)); + rb_define_const(rb_module, "CV_SEQ_FLAG_CONVEX", INT2FIX(CV_SEQ_FLAG_CONVEX)); + rb_define_const(rb_module, "CV_SEQ_FLAG_HOLE", INT2FIX(CV_SEQ_FLAG_HOLE)); + rb_define_const(rb_module, "CV_GRAPH_FLAG_ORIENTED", INT2FIX(CV_GRAPH_FLAG_ORIENTED)); + rb_define_const(rb_module, "CV_GRAPH", INT2FIX(CV_GRAPH)); + rb_define_const(rb_module, "CV_ORIENTED_GRAPH", INT2FIX(CV_ORIENTED_GRAPH)); + rb_define_const(rb_module, "CV_SEQ_POINT_SET", INT2FIX(CV_SEQ_POINT_SET)); + rb_define_const(rb_module, "CV_SEQ_POINT3D_SET", INT2FIX(CV_SEQ_POINT3D_SET)); + rb_define_const(rb_module, "CV_SEQ_POLYLINE", INT2FIX(CV_SEQ_POLYLINE)); + rb_define_const(rb_module, "CV_SEQ_POLYGON", INT2FIX(CV_SEQ_POLYGON)); + rb_define_const(rb_module, "CV_SEQ_CONTOUR", INT2FIX(CV_SEQ_CONTOUR)); + rb_define_const(rb_module, "CV_SEQ_SIMPLE_POLYGON", INT2FIX(CV_SEQ_SIMPLE_POLYGON)); + rb_define_const(rb_module, "CV_SEQ_CHAIN", INT2FIX(CV_SEQ_CHAIN)); + rb_define_const(rb_module, "CV_SEQ_CHAIN_CONTOUR", INT2FIX(CV_SEQ_CHAIN_CONTOUR)); + rb_define_const(rb_module, "CV_SEQ_POLYGON_TREE", INT2FIX(CV_SEQ_POLYGON_TREE)); + rb_define_const(rb_module, "CV_SEQ_CONNECTED_COMP", INT2FIX(CV_SEQ_CONNECTED_COMP)); + rb_define_const(rb_module, "CV_SEQ_INDEX", INT2FIX(CV_SEQ_INDEX)); + + VALUE inversion_method = rb_hash_new(); + /* {:lu, :svd, :svd_sym(:svd_symmetric)}: Inversion method */ + rb_define_const(rb_module, "INVERSION_METHOD", inversion_method); + REGISTER_HASH(inversion_method, "lu", CV_LU); + REGISTER_HASH(inversion_method, "svd", CV_SVD); + REGISTER_HASH(inversion_method, "svd_sym", CV_SVD_SYM); + REGISTER_HASH(inversion_method, "svd_symmetric", CV_SVD_SYM); + + VALUE homography_calc_method = rb_hash_new(); + /* {:all, :ransac, :lmeds}: Methods used to computed homography matrix */ + rb_define_const(rb_module, "HOMOGRAPHY_CALC_METHOD", homography_calc_method); + REGISTER_HASH(homography_calc_method, "all", 0); + REGISTER_HASH(homography_calc_method, "ransac", CV_RANSAC); + REGISTER_HASH(homography_calc_method, "lmeds", CV_LMEDS); + + VALUE depth = rb_hash_new(); + /* {:cv8u, :cv8s, :cv16u, :cv16s, :cv32s, :cv32f, :cv64f}: Depth of each pixel. */ + rb_define_const(rb_module, "DEPTH", depth); + REGISTER_HASH(depth, "cv8u", CV_8U); + REGISTER_HASH(depth, "cv8s", CV_8S); + REGISTER_HASH(depth, "cv16u", CV_16U); + REGISTER_HASH(depth, "cv16s", CV_16S); + REGISTER_HASH(depth, "cv32s", CV_32S); + REGISTER_HASH(depth, "cv32f", CV_32F); + REGISTER_HASH(depth, "cv64f", CV_64F); + + VALUE connectivity = rb_hash_new(); + /* {:aa(:anti_alias)}: Determined by the closeness of pixel values */ + rb_define_const(rb_module, "CONNECTIVITY", connectivity); + REGISTER_HASH(connectivity, "aa", CV_AA); + REGISTER_HASH(connectivity, "anti_alias", CV_AA); + + VALUE structuring_element_shape = rb_hash_new(); + /* {:rect, :cross, :ellipse, :custom}: Shape of the structuring elements */ + rb_define_const(rb_module, "STRUCTURING_ELEMENT_SHAPE", structuring_element_shape); + REGISTER_HASH(structuring_element_shape, "rect", CV_SHAPE_RECT); + REGISTER_HASH(structuring_element_shape, "cross", CV_SHAPE_CROSS); + REGISTER_HASH(structuring_element_shape, "ellipse", CV_SHAPE_ELLIPSE); + REGISTER_HASH(structuring_element_shape, "custom", CV_SHAPE_CUSTOM); + + VALUE retrieval_mode = rb_hash_new(); + /* {:external, :list, :ccomp, :tree}: Retrieval mode */ + rb_define_const(rb_module, "RETRIEVAL_MODE", retrieval_mode); + REGISTER_HASH(retrieval_mode, "external", CV_RETR_EXTERNAL); + REGISTER_HASH(retrieval_mode, "list", CV_RETR_LIST); + REGISTER_HASH(retrieval_mode, "ccomp", CV_RETR_CCOMP); + REGISTER_HASH(retrieval_mode, "tree", CV_RETR_TREE); + + VALUE approx_chain_method = rb_hash_new(); + /* {:code, :approx_none, :approx_simple, :apporx_tc89_11, :approx_tc89_kcos}: Approximation method */ + rb_define_const(rb_module, "APPROX_CHAIN_METHOD", approx_chain_method); + REGISTER_HASH(approx_chain_method, "code", CV_CHAIN_CODE); + REGISTER_HASH(approx_chain_method, "approx_none", CV_CHAIN_APPROX_NONE); + REGISTER_HASH(approx_chain_method, "approx_simple", CV_CHAIN_APPROX_SIMPLE); + REGISTER_HASH(approx_chain_method, "approx_tc89_l1", CV_CHAIN_APPROX_TC89_L1); + REGISTER_HASH(approx_chain_method, "approx_tc89_kcos", CV_CHAIN_APPROX_TC89_KCOS); + + VALUE approx_poly_method = rb_hash_new(); + /* {:dp}: Approximation method (polygon) */ + rb_define_const(rb_module, "APPROX_POLY_METHOD", approx_poly_method); + REGISTER_HASH(approx_poly_method, "dp", CV_POLY_APPROX_DP); + + VALUE match_template_method = rb_hash_new(); + /* {:sqdiff, :sqdiff_normed, :ccorr, :ccorr_normed, :ccoeff, :ccoeff_normed}: Match template method */ + rb_define_const(rb_module, "MATCH_TEMPLATE_METHOD", match_template_method); + REGISTER_HASH(match_template_method, "sqdiff", CV_TM_SQDIFF); + REGISTER_HASH(match_template_method, "sqdiff_normed", CV_TM_SQDIFF_NORMED); + REGISTER_HASH(match_template_method, "ccorr", CV_TM_CCORR); + REGISTER_HASH(match_template_method, "ccorr_normed", CV_TM_CCORR_NORMED); + REGISTER_HASH(match_template_method, "ccoeff", CV_TM_CCOEFF); + REGISTER_HASH(match_template_method, "ccoeff_normed", CV_TM_CCOEFF_NORMED); + + VALUE morphological_operation = rb_hash_new(); + /* {:open, :close, :gradient, :tophat, :blackhat}: Types of morphological operations */ + rb_define_const(rb_module, "MORPHOLOGICAL_OPERATION", morphological_operation); + REGISTER_HASH(morphological_operation, "open", CV_MOP_OPEN); + REGISTER_HASH(morphological_operation, "close", CV_MOP_CLOSE); + REGISTER_HASH(morphological_operation, "gradient", CV_MOP_GRADIENT); + REGISTER_HASH(morphological_operation, "tophat", CV_MOP_TOPHAT); + REGISTER_HASH(morphological_operation, "blackhat", CV_MOP_BLACKHAT); + + VALUE smoothing_type = rb_hash_new(); + /* {:blur_no_scale, :blur, :gaussian, :median, :bilateral}: Types of smoothing */ + rb_define_const(rb_module, "SMOOTHING_TYPE", smoothing_type); + REGISTER_HASH(smoothing_type, "blur_no_scale", CV_BLUR_NO_SCALE); + REGISTER_HASH(smoothing_type, "blur", CV_BLUR); + REGISTER_HASH(smoothing_type, "gaussian", CV_GAUSSIAN); + REGISTER_HASH(smoothing_type, "median", CV_MEDIAN); + REGISTER_HASH(smoothing_type, "bilateral", CV_BILATERAL); + + VALUE adaptive_method = rb_hash_new(); + /* {:mean_c, :gaussian_c}: Adaptive thresholding algorithm */ + rb_define_const(rb_module, "ADAPTIVE_METHOD", adaptive_method); + REGISTER_HASH(adaptive_method, "mean_c", CV_ADAPTIVE_THRESH_MEAN_C); + REGISTER_HASH(adaptive_method, "gaussian_c", CV_ADAPTIVE_THRESH_GAUSSIAN_C); + + VALUE threshold_type = rb_hash_new(); + /* {:binary, :binary_inv, :trunc, :tozero, :tozero_inv, :otsu} : Thresholding types */ + rb_define_const(rb_module, "THRESHOLD_TYPE", threshold_type); + REGISTER_HASH(threshold_type, "binary", CV_THRESH_BINARY); + REGISTER_HASH(threshold_type, "binary_inv", CV_THRESH_BINARY_INV); + REGISTER_HASH(threshold_type, "trunc", CV_THRESH_TRUNC); + REGISTER_HASH(threshold_type, "tozero", CV_THRESH_TOZERO); + REGISTER_HASH(threshold_type, "tozero_inv", CV_THRESH_TOZERO_INV); + REGISTER_HASH(threshold_type, "otsu", CV_THRESH_OTSU); + + VALUE hough_transform_method = rb_hash_new(); + /* {:standard, :probabilistic, :multi_scale} : Hough transform method */ + rb_define_const(rb_module, "HOUGH_TRANSFORM_METHOD", hough_transform_method); + REGISTER_HASH(hough_transform_method, "standard", CV_HOUGH_STANDARD); + REGISTER_HASH(hough_transform_method, "probabilistic", CV_HOUGH_PROBABILISTIC); + REGISTER_HASH(hough_transform_method, "multi_scale", CV_HOUGH_MULTI_SCALE); + REGISTER_HASH(hough_transform_method, "gradient", CV_HOUGH_GRADIENT); + + VALUE inpaint_method = rb_hash_new(); + /* {:ns, :telea} : Inpaint method */ + rb_define_const(rb_module, "INPAINT_METHOD", inpaint_method); + REGISTER_HASH(inpaint_method, "ns", CV_INPAINT_NS); + REGISTER_HASH(inpaint_method, "telea", CV_INPAINT_TELEA); + + VALUE comparison_method = rb_hash_new(); + /* Comparison method */ + rb_define_const(rb_module, "COMPARISON_METHOD", comparison_method); + REGISTER_HASH(comparison_method, "i1", CV_CONTOURS_MATCH_I1); + REGISTER_HASH(comparison_method, "i2", CV_CONTOURS_MATCH_I2); + REGISTER_HASH(comparison_method, "i3", CV_CONTOURS_MATCH_I3); + + /* color convert methods */ + rb_define_module_function(rb_module, "BGR2BGRA", RUBY_METHOD_FUNC(rb_BGR2BGRA), 1); + rb_define_module_function(rb_module, "RGB2RGBA", RUBY_METHOD_FUNC(rb_RGB2RGBA), 1); + rb_define_module_function(rb_module, "BGRA2BGR", RUBY_METHOD_FUNC(rb_BGRA2BGR), 1); + rb_define_module_function(rb_module, "RGBA2RGB", RUBY_METHOD_FUNC(rb_RGBA2RGB), 1); + rb_define_module_function(rb_module, "BGR2RGBA", RUBY_METHOD_FUNC(rb_BGR2RGBA), 1); + rb_define_module_function(rb_module, "RGB2BGRA", RUBY_METHOD_FUNC(rb_RGB2BGRA), 1); + rb_define_module_function(rb_module, "RGBA2BGR", RUBY_METHOD_FUNC(rb_RGBA2BGR), 1); + rb_define_module_function(rb_module, "BGRA2RGB", RUBY_METHOD_FUNC(rb_BGRA2RGB), 1); + rb_define_module_function(rb_module, "BGR2RGB", RUBY_METHOD_FUNC(rb_BGR2RGB), 1); + rb_define_module_function(rb_module, "RGB2BGR", RUBY_METHOD_FUNC(rb_RGB2BGR), 1); + rb_define_module_function(rb_module, "BGRA2RGBA", RUBY_METHOD_FUNC(rb_BGRA2RGBA), 1); + rb_define_module_function(rb_module, "RGBA2BGRA", RUBY_METHOD_FUNC(rb_RGBA2BGRA), 1); + rb_define_module_function(rb_module, "BGR2GRAY", RUBY_METHOD_FUNC(rb_BGR2GRAY), 1); + rb_define_module_function(rb_module, "RGB2GRAY", RUBY_METHOD_FUNC(rb_RGB2GRAY), 1); + rb_define_module_function(rb_module, "GRAY2BGR", RUBY_METHOD_FUNC(rb_GRAY2BGR), 1); + rb_define_module_function(rb_module, "GRAY2RGB", RUBY_METHOD_FUNC(rb_GRAY2RGB), 1); + rb_define_module_function(rb_module, "GRAY2BGRA", RUBY_METHOD_FUNC(rb_GRAY2BGRA), 1); + rb_define_module_function(rb_module, "GRAY2RGBA", RUBY_METHOD_FUNC(rb_GRAY2RGBA), 1); + rb_define_module_function(rb_module, "BGRA2GRAY", RUBY_METHOD_FUNC(rb_BGRA2GRAY), 1); + rb_define_module_function(rb_module, "RGBA2GRAY", RUBY_METHOD_FUNC(rb_RGBA2GRAY), 1); + rb_define_module_function(rb_module, "BGR2BGR565", RUBY_METHOD_FUNC(rb_BGR2BGR565), 1); + rb_define_module_function(rb_module, "RGB2BGR565", RUBY_METHOD_FUNC(rb_RGB2BGR565), 1); + rb_define_module_function(rb_module, "BGR5652BGR", RUBY_METHOD_FUNC(rb_BGR5652BGR), 1); + rb_define_module_function(rb_module, "BGR5652RGB", RUBY_METHOD_FUNC(rb_BGR5652RGB), 1); + rb_define_module_function(rb_module, "BGRA2BGR565", RUBY_METHOD_FUNC(rb_BGRA2BGR565), 1); + rb_define_module_function(rb_module, "RGBA2BGR565", RUBY_METHOD_FUNC(rb_RGBA2BGR565), 1); + rb_define_module_function(rb_module, "BGR5652BGRA", RUBY_METHOD_FUNC(rb_BGR5652BGRA), 1); + rb_define_module_function(rb_module, "BGR5652RGBA", RUBY_METHOD_FUNC(rb_BGR5652RGBA), 1); + rb_define_module_function(rb_module, "GRAY2BGR565", RUBY_METHOD_FUNC(rb_GRAY2BGR565), 1); + rb_define_module_function(rb_module, "BGR5652GRAY", RUBY_METHOD_FUNC(rb_BGR5652GRAY), 1); + rb_define_module_function(rb_module, "BGR2BGR555", RUBY_METHOD_FUNC(rb_BGR2BGR555), 1); + rb_define_module_function(rb_module, "RGB2BGR555", RUBY_METHOD_FUNC(rb_RGB2BGR555), 1); + rb_define_module_function(rb_module, "BGR5552BGR", RUBY_METHOD_FUNC(rb_BGR5552BGR), 1); + rb_define_module_function(rb_module, "BGR5552RGB", RUBY_METHOD_FUNC(rb_BGR5552RGB), 1); + rb_define_module_function(rb_module, "BGRA2BGR555", RUBY_METHOD_FUNC(rb_BGRA2BGR555), 1); + rb_define_module_function(rb_module, "RGBA2BGR555", RUBY_METHOD_FUNC(rb_RGBA2BGR555), 1); + rb_define_module_function(rb_module, "BGR5552BGRA", RUBY_METHOD_FUNC(rb_BGR5552BGRA), 1); + rb_define_module_function(rb_module, "BGR5552RGBA", RUBY_METHOD_FUNC(rb_BGR5552RGBA), 1); + rb_define_module_function(rb_module, "GRAY2BGR555", RUBY_METHOD_FUNC(rb_GRAY2BGR555), 1); + rb_define_module_function(rb_module, "BGR5552GRAY", RUBY_METHOD_FUNC(rb_BGR5552GRAY), 1); + rb_define_module_function(rb_module, "BGR2XYZ", RUBY_METHOD_FUNC(rb_BGR2XYZ), 1); + rb_define_module_function(rb_module, "RGB2XYZ", RUBY_METHOD_FUNC(rb_RGB2XYZ), 1); + rb_define_module_function(rb_module, "XYZ2BGR", RUBY_METHOD_FUNC(rb_XYZ2BGR), 1); + rb_define_module_function(rb_module, "XYZ2RGB", RUBY_METHOD_FUNC(rb_XYZ2RGB), 1); + rb_define_module_function(rb_module, "BGR2YCrCb", RUBY_METHOD_FUNC(rb_BGR2YCrCb), 1); + rb_define_module_function(rb_module, "RGB2YCrCb", RUBY_METHOD_FUNC(rb_RGB2YCrCb), 1); + rb_define_module_function(rb_module, "YCrCb2BGR", RUBY_METHOD_FUNC(rb_YCrCb2BGR), 1); + rb_define_module_function(rb_module, "YCrCb2RGB", RUBY_METHOD_FUNC(rb_YCrCb2RGB), 1); + rb_define_module_function(rb_module, "BGR2HSV", RUBY_METHOD_FUNC(rb_BGR2HSV), 1); + rb_define_module_function(rb_module, "RGB2HSV", RUBY_METHOD_FUNC(rb_RGB2HSV), 1); + rb_define_module_function(rb_module, "BGR2Lab", RUBY_METHOD_FUNC(rb_BGR2Lab), 1); + rb_define_module_function(rb_module, "RGB2Lab", RUBY_METHOD_FUNC(rb_RGB2Lab), 1); + rb_define_module_function(rb_module, "BayerBG2BGR", RUBY_METHOD_FUNC(rb_BayerBG2BGR), 1); + rb_define_module_function(rb_module, "BayerGB2BGR", RUBY_METHOD_FUNC(rb_BayerGB2BGR), 1); + rb_define_module_function(rb_module, "BayerRG2BGR", RUBY_METHOD_FUNC(rb_BayerRG2BGR), 1); + rb_define_module_function(rb_module, "BayerGR2BGR", RUBY_METHOD_FUNC(rb_BayerGR2BGR), 1); + rb_define_module_function(rb_module, "BayerBG2RGB", RUBY_METHOD_FUNC(rb_BayerBG2RGB), 1); + rb_define_module_function(rb_module, "BayerGB2RGB", RUBY_METHOD_FUNC(rb_BayerGB2RGB), 1); + rb_define_module_function(rb_module, "BayerRG2RGB", RUBY_METHOD_FUNC(rb_BayerRG2RGB), 1); + rb_define_module_function(rb_module, "BayerGR2RGB", RUBY_METHOD_FUNC(rb_BayerGR2RGB), 1); + rb_define_module_function(rb_module, "BGR2Luv", RUBY_METHOD_FUNC(rb_BGR2Luv), 1); + rb_define_module_function(rb_module, "RGB2Luv", RUBY_METHOD_FUNC(rb_RGB2Luv), 1); + rb_define_module_function(rb_module, "BGR2HLS", RUBY_METHOD_FUNC(rb_BGR2HLS), 1); + rb_define_module_function(rb_module, "RGB2HLS", RUBY_METHOD_FUNC(rb_RGB2HLS), 1); + rb_define_module_function(rb_module, "HSV2BGR", RUBY_METHOD_FUNC(rb_HSV2BGR), 1); + rb_define_module_function(rb_module, "HSV2RGB", RUBY_METHOD_FUNC(rb_HSV2RGB), 1); + rb_define_module_function(rb_module, "Lab2BGR", RUBY_METHOD_FUNC(rb_Lab2BGR), 1); + rb_define_module_function(rb_module, "Lab2RGB", RUBY_METHOD_FUNC(rb_Lab2RGB), 1); + rb_define_module_function(rb_module, "Luv2BGR", RUBY_METHOD_FUNC(rb_Luv2BGR), 1); + rb_define_module_function(rb_module, "Luv2RGB", RUBY_METHOD_FUNC(rb_Luv2RGB), 1); + rb_define_module_function(rb_module, "HLS2BGR", RUBY_METHOD_FUNC(rb_HLS2BGR), 1); + rb_define_module_function(rb_module, "HLS2RGB", RUBY_METHOD_FUNC(rb_HLS2RGB), 1); + + rb_define_module_function(rb_module, "build_information", RUBY_METHOD_FUNC(rb_build_information), 0); +} + +#define CREATE_CVTCOLOR_FUNC(rb_func_name, c_const_name, src_cn, dest_cn) \ + VALUE rb_func_name(VALUE klass, VALUE image) \ + { \ + VALUE dest = Qnil; \ + CvArr* img_ptr = CVARR(image); \ + try { \ + int type = cvGetElemType(img_ptr); \ + if (CV_MAT_CN(type) != src_cn) \ + rb_raise(rb_eArgError, "argument 1 should be %d-channel.", src_cn); \ + dest = cCvMat::new_mat_kind_object(cvGetSize(img_ptr), image, CV_MAT_DEPTH(type), dest_cn); \ + cvCvtColor(img_ptr, CVARR(dest), c_const_name); \ + } \ + catch (cv::Exception& e) { \ + raise_cverror(e); \ + } \ + return dest; \ + } + +CREATE_CVTCOLOR_FUNC(rb_BGR2BGRA, CV_BGR2BGRA, 3, 4); +CREATE_CVTCOLOR_FUNC(rb_RGB2RGBA, CV_RGB2RGBA, 3, 4); +CREATE_CVTCOLOR_FUNC(rb_BGRA2BGR, CV_BGRA2BGR, 4, 3); +CREATE_CVTCOLOR_FUNC(rb_RGBA2RGB, CV_RGBA2RGB, 4, 3); +CREATE_CVTCOLOR_FUNC(rb_BGR2RGBA, CV_BGR2RGBA, 3, 4); +CREATE_CVTCOLOR_FUNC(rb_RGB2BGRA, CV_RGB2BGRA, 3, 4); +CREATE_CVTCOLOR_FUNC(rb_RGBA2BGR, CV_RGBA2BGR, 4, 3); +CREATE_CVTCOLOR_FUNC(rb_BGRA2RGB, CV_BGRA2RGB, 4, 3); +CREATE_CVTCOLOR_FUNC(rb_BGR2RGB, CV_BGR2RGB, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_RGB2BGR, CV_RGB2BGR, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_BGRA2RGBA, CV_BGRA2RGBA, 4, 4); +CREATE_CVTCOLOR_FUNC(rb_RGBA2BGRA, CV_RGBA2BGRA, 4, 4); +CREATE_CVTCOLOR_FUNC(rb_BGR2GRAY, CV_BGR2GRAY, 3, 1); +CREATE_CVTCOLOR_FUNC(rb_RGB2GRAY, CV_RGB2GRAY, 3, 1); +CREATE_CVTCOLOR_FUNC(rb_GRAY2BGR, CV_GRAY2BGR, 1, 3); +CREATE_CVTCOLOR_FUNC(rb_GRAY2RGB, CV_GRAY2RGB, 1, 3); +CREATE_CVTCOLOR_FUNC(rb_GRAY2BGRA, CV_GRAY2BGRA, 1, 4); +CREATE_CVTCOLOR_FUNC(rb_GRAY2RGBA, CV_GRAY2RGBA, 1, 4); +CREATE_CVTCOLOR_FUNC(rb_BGRA2GRAY, CV_BGRA2GRAY, 4, 1); +CREATE_CVTCOLOR_FUNC(rb_RGBA2GRAY, CV_RGBA2GRAY, 4, 1); +CREATE_CVTCOLOR_FUNC(rb_BGR2BGR565, CV_BGR2BGR565, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_RGB2BGR565, CV_RGB2BGR565, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_BGR5652BGR, CV_BGR5652BGR, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_BGR5652RGB, CV_BGR5652RGB, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_BGRA2BGR565, CV_BGRA2BGR565, 4, 3); +CREATE_CVTCOLOR_FUNC(rb_RGBA2BGR565, CV_RGBA2BGR565, 4, 3); +CREATE_CVTCOLOR_FUNC(rb_BGR5652BGRA, CV_BGR5652BGRA, 3, 4); +CREATE_CVTCOLOR_FUNC(rb_BGR5652RGBA, CV_BGR5652RGBA, 3, 4); +CREATE_CVTCOLOR_FUNC(rb_GRAY2BGR565, CV_GRAY2BGR565, 1, 3); +CREATE_CVTCOLOR_FUNC(rb_BGR5652GRAY, CV_BGR5652GRAY, 3, 1); +CREATE_CVTCOLOR_FUNC(rb_BGR2BGR555, CV_BGR2BGR555, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_RGB2BGR555, CV_RGB2BGR555, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_BGR5552BGR, CV_BGR5552BGR, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_BGR5552RGB, CV_BGR5552RGB, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_BGRA2BGR555, CV_BGRA2BGR555, 4, 3); +CREATE_CVTCOLOR_FUNC(rb_RGBA2BGR555, CV_RGBA2BGR555, 4, 3); +CREATE_CVTCOLOR_FUNC(rb_BGR5552BGRA, CV_BGR5552BGRA, 3, 4); +CREATE_CVTCOLOR_FUNC(rb_BGR5552RGBA, CV_BGR5552RGBA, 3, 4); +CREATE_CVTCOLOR_FUNC(rb_GRAY2BGR555, CV_GRAY2BGR555, 1, 3); +CREATE_CVTCOLOR_FUNC(rb_BGR5552GRAY, CV_BGR5552GRAY, 3, 1); +CREATE_CVTCOLOR_FUNC(rb_BGR2XYZ, CV_BGR2XYZ, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_RGB2XYZ, CV_RGB2XYZ, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_XYZ2BGR, CV_XYZ2BGR, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_XYZ2RGB, CV_XYZ2RGB, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_BGR2YCrCb, CV_BGR2YCrCb, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_RGB2YCrCb, CV_RGB2YCrCb, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_YCrCb2BGR, CV_YCrCb2BGR, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_YCrCb2RGB, CV_YCrCb2RGB, 0, 3); +CREATE_CVTCOLOR_FUNC(rb_BGR2HSV, CV_BGR2HSV, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_RGB2HSV, CV_RGB2HSV, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_BGR2Lab, CV_BGR2Lab, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_RGB2Lab, CV_RGB2Lab, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_BayerBG2BGR, CV_BayerBG2BGR, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_BayerGB2BGR, CV_BayerGB2BGR, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_BayerRG2BGR, CV_BayerRG2BGR, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_BayerGR2BGR, CV_BayerGR2BGR, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_BayerBG2RGB, CV_BayerBG2RGB, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_BayerGB2RGB, CV_BayerGB2RGB, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_BayerRG2RGB, CV_BayerRG2RGB, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_BayerGR2RGB, CV_BayerGR2RGB, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_BGR2Luv, CV_BGR2Luv, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_RGB2Luv, CV_RGB2Luv, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_BGR2HLS, CV_BGR2HLS, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_RGB2HLS, CV_RGB2HLS, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_HSV2BGR, CV_HSV2BGR, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_HSV2RGB, CV_HSV2RGB, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_Lab2BGR, CV_Lab2BGR, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_Lab2RGB, CV_Lab2RGB, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_Luv2BGR, CV_Luv2BGR, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_Luv2RGB, CV_Luv2RGB, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_HLS2BGR, CV_HLS2BGR, 3, 3); +CREATE_CVTCOLOR_FUNC(rb_HLS2RGB, CV_HLS2RGB, 3, 3); + +VALUE +rb_build_information(VALUE klass) +{ + const char* ptr = cv::getBuildInformation().c_str(); + return rb_str_new(ptr, strlen(ptr)); +} + + +int +error_callback(int status, const char *function_name, const char *error_message, + const char *file_name, int line, void *user_data) +{ + // dummy + return 0; +} + +__NAMESPACE_END_OPENCV + +extern "C" { + void + Init_opencv() + { + cvRedirectError((CvErrorCallback)mOpenCV::error_callback); + + mOpenCV::init_ruby_module(); + + mOpenCV::cCvError::init_ruby_class(); + mOpenCV::cCvPoint::init_ruby_class(); + mOpenCV::cCvPoint2D32f::init_ruby_class(); + mOpenCV::cCvPoint3D32f::init_ruby_class(); + mOpenCV::cCvSize::init_ruby_class(); + mOpenCV::cCvSize2D32f::init_ruby_class(); + mOpenCV::cCvRect::init_ruby_class(); + mOpenCV::cCvScalar::init_ruby_class(); + mOpenCV::cCvSlice::init_ruby_class(); + mOpenCV::cCvTermCriteria::init_ruby_class(); + mOpenCV::cCvBox2D::init_ruby_class(); + mOpenCV::cCvFont::init_ruby_class(); + mOpenCV::cIplConvKernel::init_ruby_class(); + mOpenCV::cCvMoments::init_ruby_class(); + mOpenCV::cCvHuMoments::init_ruby_class(); + mOpenCV::cCvConvexityDefect::init_ruby_class(); + + mOpenCV::cCvSURFPoint::init_ruby_class(); + mOpenCV::cCvSURFParams::init_ruby_class(); + + mOpenCV::cCvMemStorage::init_ruby_class(); + + mOpenCV::cCvSeq::init_ruby_class(); + mOpenCV::mCurve::init_ruby_module(); + mOpenCV::mPointSet::init_ruby_module(); + mOpenCV::cCvChain::init_ruby_class(); + mOpenCV::cCvContour::init_ruby_class(); + mOpenCV::cCvContourTree::init_ruby_class(); + + mOpenCV::cCvMat::init_ruby_class(); + mOpenCV::cIplImage::init_ruby_class(); + mOpenCV::cCvHistogram::init_ruby_class(); + mOpenCV::cCvCapture::init_ruby_class(); + mOpenCV::cCvVideoWriter::init_ruby_class(); + + mOpenCV::cCvLine::init_ruby_class(); + mOpenCV::cCvTwoPoints::init_ruby_class(); + mOpenCV::cCvCircle32f::init_ruby_class(); + + mOpenCV::cCvFeatureTree::init_ruby_class(); + + mOpenCV::cCvConnectedComp::init_ruby_class(); + mOpenCV::cCvAvgComp::init_ruby_class(); + mOpenCV::cCvHaarClassifierCascade::init_ruby_class(); + + mOpenCV::cAlgorithm::init_ruby_class(); + mOpenCV::cFaceRecognizer::init_ruby_class(); + mOpenCV::cEigenFaces::init_ruby_class(); + mOpenCV::cFisherFaces::init_ruby_class(); + mOpenCV::cLBPH::init_ruby_class(); + + mOpenCV::mGUI::init_ruby_module(); + mOpenCV::mGUI::cWindow::init_ruby_class(); + mOpenCV::mGUI::cTrackbar::init_ruby_class(); + mOpenCV::mGUI::cMouseEvent::init_ruby_class(); + +#ifdef HAVE_ML_H + /* feature support. + mOpenCV::mMachineLearning::init_ruby_module(); + */ +#endif + +#ifdef HAVE_OPENCV2_NONFREE_NONFREE_HPP + cv::initModule_nonfree(); +#endif + } +} diff --git a/ext/opencv.h b/ext/opencv/opencv.h similarity index 62% rename from ext/opencv.h rename to ext/opencv/opencv.h index 4e2d0779..1d96cbf8 100644 --- a/ext/opencv.h +++ b/ext/opencv/opencv.h @@ -6,16 +6,26 @@ Copyright (C) 2005-2007 Masakazu Yonekura - ************************************************************/ +************************************************************/ #ifndef RUBY_OPENCV_H #define RUBY_OPENCV_H -#define __NAMESPACE_BEGIN_OPENCV namespace mOpenCV{ +#define __NAMESPACE_BEGIN_OPENCV namespace mOpenCV { #define __NAMESPACE_END_OPENCV } /* include headers */ #include +#ifdef HAVE_RUBY_VERSION_H +#include +#else #include +#endif + +// Workaround for https://bugs.ruby-lang.org/issues/11962 +#undef RB_OBJ_WB_UNPROTECT_FOR +#define RB_OBJ_WB_UNPROTECT_FOR(type, obj) \ + (RGENGC_WB_PROTECTED_##type ? \ + OBJ_WB_UNPROTECT((VALUE)(obj)) : ((VALUE)(obj))) #ifdef RUBY_WIN32_H #ifdef write @@ -27,10 +37,11 @@ #define ANYARGS () #endif -extern "C"{ +extern "C" { +#ifdef HAVE_RUBY_ST_H +#include +#else #include -#ifdef HAVE_CALLBACK_H -#include // callhack.h is ffcall header #endif #ifdef HAVE_STDARG_H @@ -43,22 +54,42 @@ extern "C"{ } // standard c headers +#define _USE_MATH_DEFINES // for VC++ #include #include #include #include // OpenCV headers -#include -#include -#include -#include -#include +#include "opencv2/core/core_c.h" +#include "opencv2/core/core.hpp" +#include "opencv2/imgproc/imgproc_c.h" +#include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/video/tracking.hpp" +#include "opencv2/video/background_segm.hpp" +#include "opencv2/features2d/features2d.hpp" +#include "opencv2/flann/flann.hpp" +#include "opencv2/calib3d/calib3d.hpp" +#include "opencv2/objdetect/objdetect.hpp" +#include "opencv2/legacy/compat.hpp" +#include "opencv2/legacy/legacy.hpp" +#include "opencv2/legacy/blobtrack.hpp" +#include "opencv2/contrib/contrib.hpp" +#include "opencv2/highgui/highgui_c.h" +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/core/internal.hpp" +#include "opencv2/photo/photo.hpp" + #ifdef HAVE_ML_H -#include +#include "opencv2/ml/ml.hpp" +#endif + +#ifdef HAVE_OPENCV2_NONFREE_NONFREE_HPP +#include "opencv2/nonfree/nonfree.hpp" #endif // Ruby/OpenCV headers +#include "cvutils.h" #include "cverror.h" #include "cvpoint.h" #include "cvpoint2d32f.h" @@ -72,6 +103,7 @@ extern "C"{ #include "cvfont.h" #include "iplconvkernel.h" #include "cvmoments.h" +#include "cvhumoments.h" #include "cvconvexitydefect.h" #include "cvpoint3d32f.h" @@ -80,31 +112,35 @@ extern "C"{ #include "cvseq.h" #include "curve.h" #include "pointset.h" -#include "point3dset.h" -#include "cvset.h" #include "cvchain.h" -#include "cvchaincode.h" #include "cvcontour.h" #include "cvcontourtree.h" #include "cvmat.h" #include "iplimage.h" -#include "cvmatnd.h" -#include "cvsparsemat.h" #include "cvhistogram.h" #include "cvcapture.h" +#include "cvvideowriter.h" -#include "cvindex.h" #include "cvline.h" #include "cvtwopoints.h" #include "cvcircle32f.h" -#include "cvcondensation.h" - #include "cvconnectedcomp.h" #include "cvavgcomp.h" #include "cvhaarclassifiercascade.h" +#include "cvsurfpoint.h" +#include "cvsurfparams.h" + +#include "cvfeaturetree.h" + +#include "algorithm.h" +#include "facerecognizer.h" +#include "eigenfaces.h" +#include "fisherfaces.h" +#include "lbph.h" + // GUI #include "gui.h" #include "window.h" @@ -112,32 +148,61 @@ extern "C"{ #include "mouseevent.h" // memory management wrapper -#define CVALLOC(type) (type*)cvAlloc(sizeof(type)) +#define RB_CVALLOC(type) (type*)rb_cvAlloc(sizeof(type)) // useful macros #define IF_INT(val, ifnone) NIL_P(val) ? ifnone : NUM2INT(val) #define IF_DBL(val, ifnone) NIL_P(val) ? ifnone : NUM2DBL(val) -#define IF_STRING(str) NIL_P(str) ? NULL : TYPE(str) == T_STRING ? rb #define IF_BOOL(val, t, f, ifnone) val == Qtrue ? t : val == Qfalse ? f : ifnone -#define IF_DEPTH(val, ifnone) NIL_P(val) ? ifnone : FIX2INT(val) - -#define RESIST_CVMETHOD(hash, str, value) rb_hash_aset(hash, ID2SYM(rb_intern(str)), INT2FIX(value)) +#define REGISTER_HASH(hash, str, value) rb_hash_aset(hash, ID2SYM(rb_intern(str)), INT2FIX(value)) +#define LOOKUP_HASH(hash, key_as_cstr) (rb_hash_lookup(hash, ID2SYM(rb_intern(key_as_cstr)))) #define maxint(a,b) ({int _a = (a), _b = (b); _a > _b ? _a : _b; }) +#ifndef BOOL2INT +#define BOOL2INT(x) ((x == Qtrue) ? 1 : 0) +#endif + +#ifndef INT2BOOL +#define INT2BOOL(x) (x ? Qtrue : Qfalse) +#endif + +// wrapper for <= 1.8 +#ifndef RARRAY_LEN +#define RARRAY_LEN(arg) (RARRAY(arg)->len) +#endif + +#ifndef RARRAY_PTR +#define RARRAY_PTR(arg) (RARRAY(arg)->ptr) +#endif + +#ifndef RSTRING_LEN +#define RSTRING_LEN(arg) (RSTRING(arg)->len) +#endif + +#ifndef RSTRING_PTR +#define RSTRING_PTR(arg) (RSTRING(arg)->ptr) +#endif + +#ifndef DBL2NUM +#define DBL2NUM(dbl) (rb_float_new(dbl)) +#endif + + // OpenCV module __NAMESPACE_BEGIN_OPENCV void mark_root_object(void *ptr); VALUE lookup_root_object(void *ptr); -void resist_root_object(void *ptr, VALUE root); -void unresist_object(void *ptr); +void register_root_object(void *ptr, VALUE root); +void unregister_object(void *ptr); void free_object(void *ptr); void release_object(void *ptr); +void release_iplconvkernel_object(void *ptr); VALUE rb_module_opencv(); -void define_ruby_module(); +void init_ruby_module(); // Ruby/OpenCV inline functions inline CvArr* @@ -148,6 +213,21 @@ CVARR(VALUE object) return ptr; } +inline CvArr* +CVARR_WITH_CHECK(VALUE object) +{ + Check_Type(object, T_DATA); + void *ptr = DATA_PTR(object); + if (CV_IS_IMAGE(ptr) || CV_IS_MAT(ptr) || CV_IS_SEQ(ptr) || + CV_IS_MATND(ptr) || CV_IS_SPARSE_MAT(ptr)) { + return CVARR(object); + } + else { + raise_compatible_typeerror(object, (char*)"CvArr"); + } + return NULL; +} + inline VALUE OPENCV_OBJECT(VALUE klass, void *ptr) { @@ -155,62 +235,53 @@ OPENCV_OBJECT(VALUE klass, void *ptr) } inline VALUE -GENERIC_OBJECT(VALUE klass, void *ptr) +IPLCONVKERNEL_OBJECT(VALUE klass, void *ptr) { - return Data_Wrap_Struct(klass, 0, 0, ptr); + return Data_Wrap_Struct(klass, 0, release_iplconvkernel_object, ptr); } inline VALUE -DEPEND_OBJECT(VALUE klass, void *ptr, VALUE root) +GENERIC_OBJECT(VALUE klass, void *ptr) { - resist_root_object(ptr, root); - return Data_Wrap_Struct(klass, mark_root_object, free_object, ptr); + return Data_Wrap_Struct(klass, 0, -1, ptr); } inline VALUE -REFER_OBJECT(VALUE klass, void *ptr, VALUE root) +DEPEND_OBJECT(VALUE klass, void *ptr, VALUE root) { - resist_root_object(ptr, root); - return Data_Wrap_Struct(klass, mark_root_object, unresist_object, ptr); + register_root_object(ptr, root); + return Data_Wrap_Struct(klass, mark_root_object, free_object, ptr); } inline VALUE -CONVERT(VALUE object, VALUE klass) +REFER_OBJECT(VALUE klass, void *ptr, VALUE root) { - VALUE method_name = rb_str_concat(rb_str_new2("from_"), rb_str_new2(rb_obj_classname(object))); - VALUE result = rb_funcall(klass, rb_intern(StringValueCStr(method_name)), 1, object); - if(CLASS_OF(result) != klass) - rb_raise(rb_eTypeError, "require %s, but return %s.", rb_class2name(klass), rb_class2name(CLASS_OF(result))); - return result; + register_root_object(ptr, root); + return Data_Wrap_Struct(klass, mark_root_object, unregister_object, ptr); } inline int CVMETHOD(const char *name, VALUE method, int ifnone = 0) { VALUE value; - switch(TYPE(method)){ + switch (TYPE(method)) { case T_NIL: return ifnone; case T_FIXNUM: return FIX2INT(method); - case T_STRING: - method = rb_str_intern(method); - case T_SYMBOL: - value = rb_hash_aref(rb_const_get(rb_module_opencv(), rb_intern(name)), method); - if(NIL_P(value)){ - rb_warn("invalid opencv method type (see OpenCV::%s)", name); - return ifnone; - }else{ - return FIX2INT(value); - }if (rb_obj_is_kind_of(value, rb_cNumeric)) + case T_STRING: + method = rb_str_intern(method); + case T_SYMBOL: + value = rb_hash_lookup(rb_const_get(rb_module_opencv(), rb_intern(name)), method); + return NIL_P(value) ? ifnone : FIX2INT(value); default: - rb_raise(rb_eTypeError, ""); + raise_typeerror(method, rb_cSymbol); } - return 0; + return ifnone; } inline int -TRUE_OR_FALSE(VALUE object, int ifnone) +TRUE_OR_FALSE(VALUE object, int ifnone = 0) { int value = ifnone; switch (TYPE(object)) { @@ -223,11 +294,40 @@ TRUE_OR_FALSE(VALUE object, int ifnone) case T_NIL: break; default: - rb_warn("argument should be true or false."); + break; } return value; } +inline int +CV2IPL_DEPTH(int depth) +{ + switch (depth) { + case CV_8U: + return IPL_DEPTH_8U; + break; + case CV_8S: + return IPL_DEPTH_8S; + break; + case CV_16U: + return IPL_DEPTH_16U; + break; + case CV_32F: + return IPL_DEPTH_32F; + break; + case CV_32S: + return IPL_DEPTH_32S; + break; + case CV_64F: + return IPL_DEPTH_64F; + break; + default: + rb_raise(rb_eArgError, "Invalid depth: %d", depth); + break; + } + return 0; +} + VALUE rb_BGR2BGRA(VALUE klass, VALUE image); VALUE rb_RGB2RGBA(VALUE klass, VALUE image); VALUE rb_BGRA2BGR(VALUE klass, VALUE image); @@ -301,57 +401,8 @@ VALUE rb_Luv2RGB(VALUE klass, VALUE image); VALUE rb_HLS2BGR(VALUE klass, VALUE image); VALUE rb_HLS2RGB(VALUE klass, VALUE image); -__NAMESPACE_END_OPENCV - -inline VALUE -extract_options_from_args_bang(VALUE ary) -{ - return (RARRAY(ary)->len > 0 && rb_obj_is_kind_of(RARRAY(ary)->ptr[RARRAY(ary)->len -1], rb_cHash)) ? rb_ary_pop(ary) : rb_hash_new(); -} - -/* -inline VALUE -assert_valid_keys(VALUE keys, VALUE valid_keys) -{ - VALUE unknown_keys = rb_funcall(keys, rb_intern("-"), 1, rb_funcall(valid_keys, rb_intern("flatten"), 0)); - if (NUM2INT(rb_funcall(unknown_keys, rb_intern("empty?"), 0)) != 0){ - rb_raise(rb_eArgError, "Unknown key(s): %s", - RSTRING(rb_funcall(unknown_keys, rb_intern("join"), 1, rb_str_new2(", ")))->ptr); - } - return Qnil; -} -*/ - /* -inline void -assert_valid_keys(VALUE options, int n, ...){ - va_list valid_keys; - if (!(n > 0)) {return;} - VALUE unknown_keys = rb_funcall(options, rb_intern("keys"), 0); - va_start(valid_keys, n); - for (int i = 0; i < n; i++) - rb_ary_delete(unknown_keys, ID2SYM(rb_intern(va_arg(valid_keys, char*)))); - if (RARRAY(unknown_keys)->len > 0) - rb_raise(rb_eArgError, "Unknown key(s): %s", - RSTRING(rb_funcall(unknown_keys, rb_intern("join"), 1, rb_str_new2(", ")))->ptr); - va_end(valid_keys); -} +VALUE rb_build_information(VALUE klass); -inline VALUE -validate_option(VALUE options, const *char key, char *ifnone, int n, ...){ - va_list valid_values; - VALUE value = rb_hash_aref(options, ID2SYM(rb_intern(key))); - if (!value || !(n > 0)) {return ifnone;} - va_start(valid_values, n); - for (int i = 0; i < n; i++){ - if (!strcmp(StringValueCStr(value), va_arg(valid_values, char*))){ - rb_warn("Option :%s value :%s does not defined. Default value :%s is used.", StringValueCStr(value), ); - return ifnone; - } - } - va_end(valid_values); - return value; -} +__NAMESPACE_END_OPENCV -#define OPTIONS(value, hash, key, default) value = ((value = rb_hash_aref(hash, ID2SYM(rb_intern(key)))) ? value : default) - */ #endif // RUBY_OPENCV_H diff --git a/ext/opencv/pointset.cpp b/ext/opencv/pointset.cpp new file mode 100644 index 00000000..3afbcddd --- /dev/null +++ b/ext/opencv/pointset.cpp @@ -0,0 +1,280 @@ +/************************************************************ + + pointset.cpp - + + $Author: lsxi $ + + Copyright (C) 2005-2006 Masakazu Yonekura + +************************************************************/ +#include "pointset.h" +/* + * Document-class: OpenCV::PointSet + */ + +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_POINT_SET + +VALUE module; + +VALUE +rb_module() +{ + return module; +} + +/* + * call-seq: + * contour_area -> float + * + * Calculates area of the whole contour or contour section. + * + * note: Orientation of the contour affects the area sign, thus the method may return negative result. + */ +VALUE +rb_contour_area(int argc, VALUE *argv, VALUE self) +{ + VALUE slice; + rb_scan_args(argc, argv, "01", &slice); + double area = 0; + try { + area = cvContourArea(CVARR(self), NIL_P(slice) ? CV_WHOLE_SEQ : VALUE_TO_CVSLICE(slice)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return rb_float_new(area); +} + +/* + * call-seq: + * fit_ellipse2 -> cvbox2d + * + * Return fits ellipse to set of 2D points. + */ +VALUE +rb_fit_ellipse2(VALUE self) +{ + CvBox2D box; + try { + box = cvFitEllipse2(CVARR(self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return cCvBox2D::new_object(box); +} + +/* + * call-seq: + * convex_hull2([orientation_clockwise = true]) -> cvcontour + * + * Finds convex hull of 2D point set using Sklansky's algorithm. + * + * orientation_clockwise: Desired orientation of convex hull (true: clockwise, false: counter clockwise). + */ +VALUE +rb_convex_hull2(int argc, VALUE *argv, VALUE self) +{ + VALUE clockwise, return_points; + rb_scan_args(argc, argv, "02", &clockwise, &return_points); + VALUE storage = cCvMemStorage::new_object(); + CvSeq *hull = NULL; + int return_pts = TRUE_OR_FALSE(return_points, 1); + try { + hull = cvConvexHull2(CVSEQ(self), CVMEMSTORAGE(storage), + TRUE_OR_FALSE(clockwise, 1) ? CV_CLOCKWISE : CV_COUNTER_CLOCKWISE, + return_pts); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return cCvSeq::new_sequence(cCvContour::rb_class(), hull, cCvPoint::rb_class(), storage); +} + +/* + * call-seq: + * check_contour_convexity -> true or false + * + * Tests whether the input contour is convex or not. The contour must be simple, i.e. without self-intersections. + */ +VALUE +rb_check_contour_convexity(VALUE self) +{ + int convexity = 0; + try { + convexity = cvCheckContourConvexity(CVARR(self)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return convexity ? Qtrue : Qfalse; +} + +/* + * call-seq: + * convexity_defects(hull) -> cvseq(include CvConvexityDefect) + * + * Finds convexity defects of contour. + */ +VALUE +rb_convexity_defects(VALUE self, VALUE hull) +{ + CvSeq *defects = NULL; + CvSeq *hull_seq = CVSEQ_WITH_CHECK(hull); + VALUE storage = cCvMemStorage::new_object(); + CvMemStorage *storage_ptr = CVMEMSTORAGE(storage); + try { + defects = cvConvexityDefects(CVSEQ(self), hull_seq, storage_ptr); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return cCvSeq::new_sequence(cCvSeq::rb_class(), defects, cCvConvexityDefect::rb_class(), storage); +} + +/* + * call-seq: + * min_area_rect2 -> cvbox2d + * + * Finds circumscribed rectangle of minimal area for given 2D point set. + */ +VALUE +rb_min_area_rect2(VALUE self) +{ + VALUE storage = cCvMemStorage::new_object(); + CvBox2D rect; + try { + rect = cvMinAreaRect2(CVARR(self), CVMEMSTORAGE(storage)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return cCvBox2D::new_object(rect); +} + +/* + * call-seq: + * min_enclosing_circle -> cvcircle32f + * + * Finds circumscribed circle of minimal area for given 2D point set. + */ +VALUE +rb_min_enclosing_circle(VALUE self) +{ + VALUE circle = cCvCircle32f::rb_allocate(cCvCircle32f::rb_class()); + int success = 0; + try { + success = cvMinEnclosingCircle(CVARR(self), &CVCIRCLE32F(circle)->center, + &CVCIRCLE32F(circle)->radius); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return success ? circle : Qnil; +} + +void +init_ruby_module() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); +#endif + + if (module) + return; + /* + * opencv = rb_define_module("OpenCV"); + * + * note: this comment is used by rdoc. + */ + VALUE opencv = rb_module_opencv(); + module = rb_define_module_under(opencv, "PointSet"); + rb_define_method(module, "contour_area", RUBY_METHOD_FUNC(rb_contour_area), -1); + rb_define_method(module, "fit_ellipse2", RUBY_METHOD_FUNC(rb_fit_ellipse2), 0); + + rb_define_method(module, "convex_hull2", RUBY_METHOD_FUNC(rb_convex_hull2), -1); + rb_define_method(module, "check_contour_convexity", RUBY_METHOD_FUNC(rb_check_contour_convexity), 0); + rb_define_alias(module, "convexity?", "check_contour_convexity"); + rb_define_method(module, "convexity_defects", RUBY_METHOD_FUNC(rb_convexity_defects), 1); + rb_define_method(module, "min_area_rect2", RUBY_METHOD_FUNC(rb_min_area_rect2), 0); + rb_define_method(module, "min_enclosing_circle", RUBY_METHOD_FUNC(rb_min_enclosing_circle), 0); +} + +__NAMESPACE_END_POINT_SET + +int +CVPOINTS_FROM_POINT_SET(VALUE object, CvPoint **pointset) +{ + if (rb_obj_is_kind_of(object, cCvSeq::rb_class())) { + if (CV_IS_SEQ_POINT_SET(CVSEQ(object))) { + *pointset = (CvPoint*)cvCvtSeqToArray(CVSEQ(object), + rb_cvAlloc(CVSEQ(object)->total * CVSEQ(object)->elem_size)); + return CVSEQ(object)->total; + } + else { + rb_raise(rb_eTypeError, "sequence does not contain %s or %s.", + rb_class2name(cCvPoint::rb_class()), rb_class2name(cCvPoint2D32f::rb_class())); + } + } + else if (rb_obj_is_kind_of(object, cCvMat::rb_class())) { + /* to do */ + rb_raise(rb_eNotImpError, "CvMat to CvSeq conversion not implemented."); + } + else if (rb_obj_is_kind_of(object, rb_cArray)) { + int len = RARRAY_LEN(object); + *pointset = (CvPoint*)rb_cvAlloc(len * sizeof(CvPoint)); + ID id_x = rb_intern("x"); + ID id_y = rb_intern("y"); + for (int i = 0; i < len; ++i) { + (*pointset)[i].x = NUM2INT(rb_funcall(rb_ary_entry(object, i), id_x, 0)); + (*pointset)[i].y = NUM2INT(rb_funcall(rb_ary_entry(object, i), id_y, 0)); + } + return len; + } + else { + rb_raise(rb_eTypeError, "Can't convert CvSeq(PointSet)."); + } +} + +CvSeq* +VALUE_TO_POINT_SET(VALUE object) +{ + CvSeq *seq = 0; + VALUE tmp, storage; + int length; + CvPoint2D32f p32; + if (rb_obj_is_kind_of(object, cCvSeq::rb_class())) { + seq = CVSEQ(object); + if (CV_IS_SEQ_POINT_SET(seq)) { + return seq; + } + else { + rb_raise(rb_eTypeError, "sequence is not contain %s or %s.", rb_class2name(cCvPoint::rb_class()), rb_class2name(cCvPoint2D32f::rb_class())); + } + } + else if (rb_obj_is_kind_of(object, cCvMat::rb_class())) { + /* to do */ + rb_raise(rb_eNotImpError, "CvMat to CvSeq conversion not implemented."); + } + else if (rb_obj_is_kind_of(object, rb_cArray)) { + //pointset = cCvSeq::new_sequence(cCvSeq::rb_class(), ) + length = RARRAY_LEN(object); + storage = cCvMemStorage::new_object(); + seq = cvCreateSeq(CV_SEQ_POINT_SET, sizeof(CvSeq), sizeof(CvPoint), CVMEMSTORAGE(storage)); + for (int i = 0; i < RARRAY_LEN(object); i++) { + p32.x = NUM2DBL(rb_funcall(rb_ary_entry(object, i), rb_intern("x"), 0)); + p32.y = NUM2DBL(rb_funcall(rb_ary_entry(object, i), rb_intern("y"), 0)); + cvSeqPush(seq, &p32); + } + tmp = cCvSeq::new_sequence(cCvSeq::rb_class(), seq, cCvPoint2D32f::rb_class(), storage); + return seq; + } + else { + rb_raise(rb_eTypeError, "Can't convert CvSeq(PointSet)."); + } +} + +__NAMESPACE_END_OPENCV + diff --git a/ext/pointset.h b/ext/opencv/pointset.h similarity index 84% rename from ext/pointset.h rename to ext/opencv/pointset.h index 4eebc4e3..99c38f72 100644 --- a/ext/pointset.h +++ b/ext/opencv/pointset.h @@ -10,26 +10,25 @@ #ifndef RUBY_OPENCV_POINTSET_H #define RUBY_OPENCV_POINTSET_H -#define __NAMESPACE_BEGIN_POINT_SET namespace mPointSet{ +#define __NAMESPACE_BEGIN_POINT_SET namespace mPointSet { #define __NAMESPACE_END_POINT_SET } -#include"opencv.h" +#include "opencv.h" __NAMESPACE_BEGIN_OPENCV __NAMESPACE_BEGIN_POINT_SET VALUE rb_module(); -void define_ruby_module(); +void init_ruby_module(); VALUE rb_contour_area(int argc, VALUE *argv, VALUE self); -VALUE rb_fit_ellipse(VALUE self); +VALUE rb_fit_ellipse2(VALUE self); +VALUE rb_convex_hull2(int argc, VALUE *argv, VALUE self); VALUE rb_fit_line(int argc, VALUE *argv, VALUE self); -VALUE rb_convex_hull(int argc, VALUE *argv, VALUE self); VALUE rb_check_contour_convexity(VALUE self); -VALUE rb_convexity_defects(int argc, VALUE *argv, VALUE self); -VALUE rb_min_area_rect(VALUE self); +VALUE rb_convexity_defects(VALUE self, VALUE hull); +VALUE rb_min_area_rect2(VALUE self); VALUE rb_min_enclosing_circle(VALUE self); -VALUE rb_calc_pgh(VALUE self); __NAMESPACE_END_POINT_SET diff --git a/ext/trackbar.cpp b/ext/opencv/trackbar.cpp similarity index 64% rename from ext/trackbar.cpp rename to ext/opencv/trackbar.cpp index 4d4e2eb9..2c419262 100644 --- a/ext/trackbar.cpp +++ b/ext/opencv/trackbar.cpp @@ -7,9 +7,7 @@ Copyright (C) 2005 Masakazu Yonekura ************************************************************/ -#ifdef HAVE_CALLBACK_H - -#include"trackbar.h" +#include "trackbar.h" /* * Document-class: OpenCV::GUI::Trackbar * @@ -23,60 +21,43 @@ __NAMESPACE_BEGIN_TRACKBAR VALUE rb_klass; -VALUE rb_class(){ +VALUE rb_class() { return rb_klass; } -void define_ruby_class(){ - if(rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * GUI = rb_define_module_under(opencv, "GUI"); - * - * note: this comment is used by rdoc. - */ - VALUE GUI = rb_module_GUI(); - rb_klass = rb_define_class_under(GUI, "Trackbar", rb_cObject); - rb_define_alloc_func(rb_klass, rb_allocate); - rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); - rb_define_method(rb_klass, "name", RUBY_METHOD_FUNC(rb_name), 0); - rb_define_method(rb_klass, "max", RUBY_METHOD_FUNC(rb_max), 0); - rb_define_method(rb_klass, "value", RUBY_METHOD_FUNC(rb_value), 0); - rb_define_method(rb_klass, "value=", RUBY_METHOD_FUNC(rb_set_value), 1); -} - -VALUE rb_allocate(VALUE klass){ +VALUE rb_allocate(VALUE klass) { Trackbar *ptr; - return Data_Make_Struct(klass, Trackbar, mark, free, ptr); + return Data_Make_Struct(klass, Trackbar, trackbar_mark, trackbar_free, ptr); } -void mark(void *ptr){ +void trackbar_mark(void *ptr) { rb_gc_mark(((Trackbar*)ptr)->block); } -void free(void *ptr){ - //::free(((Trackbar*)ptr)->name); - ::free(ptr); +void trackbar_free(void *ptr) { + Trackbar *trackbar = (Trackbar*)ptr; + free(trackbar->name); + free(trackbar); } /* * call-seq: - * new(name,maxval[,val],&block) - * new(name,maxval[,val]){|value| ... } + * new(name,maxval[,val],&block) + * new(name,maxval[,val]){|value| ... } * * Create new Trackbar. * name should be String. - * maxval and val should be Fixnum. + * maxval and val should be Integer. * When Trackbar adjuster changed, block will be called. */ -VALUE rb_initialize(int argc, VALUE *argv, VALUE self){ +VALUE rb_initialize(int argc, VALUE *argv, VALUE self) { VALUE name, maxval, val, block; rb_scan_args(argc, argv, "21&", &name, &maxval, &val, &block); - if(NIL_P(block)){rb_raise(rb_eArgError, "block not given.");} + if (NIL_P(block)) + rb_raise(rb_eArgError, "block not given."); Check_Type(name, T_STRING); Trackbar *trackbar = TRACKBAR(self); - trackbar->name = strcpy(ALLOC_N(char, RSTRING(name)->len), StringValueCStr(name)); + trackbar->name = strcpy(ALLOC_N(char, RSTRING_LEN(name) + 1), StringValueCStr(name)); trackbar->maxval = NUM2INT(maxval); trackbar->val = IF_INT(val, 0); trackbar->block = block; @@ -86,22 +67,22 @@ VALUE rb_initialize(int argc, VALUE *argv, VALUE self){ /* * Return trackbar name. */ -VALUE rb_name(VALUE self){ +VALUE rb_name(VALUE self) { return rb_str_new2(TRACKBAR(self)->name); } /* * Return the maximum value that can be taken this trackbar. */ -VALUE rb_max(VALUE self){ - return INT2FIX(TRACKBAR(self)->maxval); +VALUE rb_max(VALUE self) { + return INT2NUM(TRACKBAR(self)->maxval); } /* * Return the value of this trackbar. */ -VALUE rb_value(VALUE self){ - return INT2FIX(TRACKBAR(self)->val); +VALUE rb_value(VALUE self) { + return INT2NUM(TRACKBAR(self)->val); } /* @@ -110,13 +91,37 @@ VALUE rb_value(VALUE self){ * * Set trackbar value. */ -VALUE rb_set_value(VALUE self, VALUE val){ +VALUE rb_set_value(VALUE self, VALUE val) { TRACKBAR(self)->val = NUM2INT(val); return self; } + +void init_ruby_class() { +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); + VALUE GUI = rb_define_module_under(opencv, "GUI"); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * GUI = rb_define_module_under(opencv, "GUI"); + * + * note: this comment is used by rdoc. + */ + VALUE GUI = rb_module_GUI(); + rb_klass = rb_define_class_under(GUI, "Trackbar", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "name", RUBY_METHOD_FUNC(rb_name), 0); + rb_define_method(rb_klass, "max", RUBY_METHOD_FUNC(rb_max), 0); + rb_define_method(rb_klass, "value", RUBY_METHOD_FUNC(rb_value), 0); + rb_define_method(rb_klass, "value=", RUBY_METHOD_FUNC(rb_set_value), 1); +} __NAMESPACE_END_TRACKBAR __NAMESPACE_END_GUI __NAMESPACE_END_OPENCV -#endif // HAVE_CALLBACK_H diff --git a/ext/trackbar.h b/ext/opencv/trackbar.h similarity index 67% rename from ext/trackbar.h rename to ext/opencv/trackbar.h index f404a714..1ed87bfb 100644 --- a/ext/trackbar.h +++ b/ext/opencv/trackbar.h @@ -7,8 +7,6 @@ Copyright (C) 2005 Masakazu Yonekura ************************************************************/ -#ifdef HAVE_CALLBACK_H - #ifndef RUBY_OPENCV_GUI_H #include "gui.h" #endif @@ -16,30 +14,30 @@ #ifndef RUBY_OPENCV_GUI_TRACKBAR_H #define RUBY_OPENCV_GUI_TRACKBAR_H -#include"opencv.h" +#include "opencv.h" -#define __NAMESPACE_BEGIN_TRACKBAR namespace cTrackbar{ +#define __NAMESPACE_BEGIN_TRACKBAR namespace cTrackbar { #define __NAMESPACE_END_TRACKBAR } __NAMESPACE_BEGIN_OPENCV __NAMESPACE_BEGIN_GUI -typedef struct Trackbar{ +typedef struct Trackbar { char *name; int maxval; int val; VALUE block; -}Trackbar; +} Trackbar; __NAMESPACE_BEGIN_TRACKBAR VALUE rb_class(); -void define_ruby_class(); +void init_ruby_class(); VALUE rb_allocate(VALUE klass); -void mark(void *ptr); -void free(void *ptr); +void trackbar_mark(void *ptr); +void trackbar_free(void *ptr); VALUE rb_initialize(int argc, VALUE *argv, VALUE self); VALUE rb_name(VALUE self); @@ -49,17 +47,23 @@ VALUE rb_set_value(VALUE self, VALUE val); __NAMESPACE_END_TRACKBAR - -inline Trackbar *TRACKBAR(VALUE object){ +inline Trackbar* +TRACKBAR(VALUE object) { Trackbar *ptr; Data_Get_Struct(object, Trackbar, ptr); return ptr; } -__NAMESPACE_END_GUI +inline Trackbar* +TRACKBAR_WITH_CHECK(VALUE object) { + if (!rb_obj_is_kind_of(object, cTrackbar::rb_class())) { + raise_typeerror(object, cTrackbar::rb_class()); + } + return TRACKBAR(object); +} +__NAMESPACE_END_GUI __NAMESPACE_END_OPENCV #endif // RUBY_OPENCV_GUI_TRACKBAR_H -#endif // HAVE_CALLBACK_H diff --git a/ext/opencv/window.cpp b/ext/opencv/window.cpp new file mode 100644 index 00000000..8dd64bff --- /dev/null +++ b/ext/opencv/window.cpp @@ -0,0 +1,377 @@ +/************************************************************ + + window.cpp - + + $Author: lsxi $ + + Copyright (C) 2005-2006 Masakazu Yonekura + +************************************************************/ +#include "window.h" + +/* + * Document-class: OpenCV::GUI::Window + * + * Simple Window wedget to show images(CvMat/IplImage). + * + * Sample: + * image = OpenCV::IplImage::load("opencv.bmp") #=> load image + * window = OpenCV::GUI::Window.new("simple viewer")#=> create new window named "simaple viewer" + * window.show(image) #=> show image + */ +__NAMESPACE_BEGIN_OPENCV +__NAMESPACE_BEGIN_GUI +__NAMESPACE_BEGIN_WINDOW + +int num_windows = 0; +VALUE rb_klass; + +VALUE +rb_class() +{ + return rb_klass; +} + +VALUE +rb_allocate(VALUE klass) +{ + Window *ptr; + return Data_Make_Struct(klass, Window, window_mark, window_free, ptr); +} + +void +window_mark(void *ptr) +{ + Window* window_ptr = (Window*)ptr; + rb_gc_mark(window_ptr->name); + rb_gc_mark(window_ptr->image); + rb_gc_mark(window_ptr->trackbars); + rb_gc_mark(window_ptr->blocks); +} + +void +window_free(void *ptr) +{ + free(ptr); +} + +/* + * Creates a window. + * + * @overload new(name, flags = CV_WINDOW_AUTOSIZE) + * @param name [String] Name of the window in the window caption that may be used as a window identifier. + * @param flags [Integer] Flags of the window. The supported flags are: + * * CV_WINDOW_AUTOSIZE - If this is set, the window size is automatically adjusted + * to fit the displayed image, and you cannot change the window size manually. + * * CV_WINDOW_NORMAL - If this is set, the user can resize the window (no constraint). + * * CV_WINDOW_OPENGL - If this is set, the window will be created with OpenGL support. + * @opencv_func cvNamedWindow + */ +VALUE +rb_initialize(int argc, VALUE *argv, VALUE self) +{ + VALUE name, flags; + rb_scan_args(argc, argv, "11", &name, &flags); + Check_Type(name, T_STRING); + char* name_str = StringValueCStr(name); + if (cvGetWindowHandle(name_str) != NULL) { + rb_raise(rb_eStandardError, "window name should be unique."); + } + + int mode = CV_WINDOW_AUTOSIZE; + if (argc == 2) { + Check_Type(flags, T_FIXNUM); + mode = FIX2INT(flags); + } + + Window* self_ptr = WINDOW(self); + self_ptr->name = name; + self_ptr->trackbars = rb_ary_new(); + self_ptr->blocks = rb_ary_new(); + try { + cvNamedWindow(name_str, mode); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + num_windows++; + return self; +} + +/* + * Return alive status of window. Return true if alive, otherwise return false. + */ +VALUE +rb_alive_q(VALUE self) +{ + const char* name_str = GET_WINDOW_NAME(self); + return (cvGetWindowHandle(name_str) == NULL) ? Qfalse : Qtrue; +} + +/* + * Destroys a window. alive status of window be false. + */ +VALUE +rb_destroy(VALUE self) +{ + const char* name_str = GET_WINDOW_NAME(self); + try { + cvDestroyWindow(name_str); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + num_windows--; + return self; +} + +/* + * Destorys all the windows. + */ +VALUE +rb_destroy_all(VALUE klass) +{ + if (num_windows > 0) { + try { + cvDestroyAllWindows(); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + num_windows = 0; + } + return Qnil; +} + +/* + * Resizes window to the specified size. + * + * @overload resize(size) + * @param size [CvSize] The new window size. + * @overload resize(width, height) + * @param width [Integer] The new window width. + * @param height [Integer] The new window height. + * @opencv_func cvResizeWindow + */ +VALUE +rb_resize(int argc, VALUE *argv, VALUE self) +{ + int width = 0; + int height = 0; + switch (argc) { + case 1: { + CvSize size = VALUE_TO_CVSIZE(argv[0]); + width = size.width; + height = size.height; + break; + } + case 2: + width = NUM2INT(argv[0]); + height = NUM2INT(argv[1]); + break; + default: + rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)"); + break; + } + try { + cvResizeWindow(GET_WINDOW_NAME(self), width, height); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Moves window to the specified position. + * + * @overload move(point) + * @param point [CvPoint] The new coordinate of the window. + * @overload move(x, y) + * @param x [Integer] The new x-coordinate of the window. + * @param y [Integer] The new y-coordinate of the window. + * @opencv_func cvMoveWindow + */ +VALUE +rb_move(int argc, VALUE *argv, VALUE self) +{ + int x = 0; + int y = 0; + switch (argc) { + case 1: { + CvPoint point = VALUE_TO_CVPOINT(argv[0]); + x = point.x; + y = point.y; + break; + } + case 2: + x = NUM2INT(argv[0]); + y = NUM2INT(argv[1]); + break; + default: + rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)"); + break; + } + try { + cvMoveWindow(GET_WINDOW_NAME(self), x, y); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +/* + * Displays an image in the specified window. + * + * @overload show_image(image) + * @param image [CvMat] Image to be shown. + * @opencv_func cvShowImage + */ +VALUE +rb_show_image(VALUE self, VALUE img) +{ + CvArr* image = CVARR_WITH_CHECK(img); + WINDOW(self)->image = img; + try { + cvShowImage(GET_WINDOW_NAME(self), image); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + return self; +} + +void +trackbar_callback(int value, void* block) +{ + rb_funcall((VALUE)block, rb_intern("call"), 1, INT2NUM(value)); +} + +/* + * Creates or sets a trackbar and attaches it to the specified window. + * + * @overload set_trackbar(trackbar) + * @param trackbar [TrackBar] The trackbar to set. + * + * @overload set_trackbar(name, count, value = nil) { |value| ... } + * @param name [String] Name of the created trackbar. + * @param count [Integer] Maximal position of the slider. The minimal position is always 0. + * @param value [Integer] Optional value to an integer variable whose value reflects the position of the slider. + * Upon creation, the slider position is defined by this variable. + * @yield [value] Function to be called every time the slider changes position. + * @yieldparam value [Integer] The trackbar position. + * @opencv_func cv::createTrackbar + */ +VALUE +rb_set_trackbar(int argc, VALUE *argv, VALUE self) +{ + VALUE trackbar; + if (argc == 1) { + trackbar = argv[0]; + } + else { + trackbar = cTrackbar::rb_initialize(argc, argv, cTrackbar::rb_allocate(cTrackbar::rb_class())); + } + Trackbar *trackbar_ptr = TRACKBAR_WITH_CHECK(trackbar); + try { + cv::createTrackbar(trackbar_ptr->name, GET_WINDOW_NAME(self), &(trackbar_ptr->val), trackbar_ptr->maxval, + (cv::TrackbarCallback)trackbar_callback, (void*)(trackbar_ptr->block)); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + rb_ary_push(WINDOW(self)->trackbars, trackbar); + + return trackbar; +} + +void +on_mouse(int event, int x, int y, int flags, void* param) +{ + VALUE block = (VALUE)param; + if (rb_obj_is_kind_of(block, rb_cProc)) { + rb_funcall(block, rb_intern("call"), 1, cMouseEvent::new_object(event, x, y, flags)); + } +} + +/* + * Sets mouse handler for the specified window. + * + * @overload set_mouse_callback { |mouse_event| ... } + * @yield [mouse_event] Mouse callback. + * @yieldparam mouse_event [MouseEvent] Mouse event + * + * @example display mouse event on console + * window = OpenCV::GUI::Window.new "sample window" + * image = OpenCV::IplImage::load "sample.png" + * window.show(image) + * window.set_mouse_callback {|mouse| + * e = "#{mouse.x}, #{mouse.y} : #{mouse.event} : " + * e << "" if mouse.left_button? + * e << "" if mouse.right_button? + * e << "" if mouse.middle_button? + * e << "[CTRL]" if mouse.ctrl_key? + * e << "[SHIFT]" if mouse.shift_key? + * e << "[ALT]" if mouse.alt_key? + * puts e + * } + * OpenCV::GUI::wait_key + */ +VALUE +rb_set_mouse_callback(int argc, VALUE* argv, VALUE self) +{ + if (!rb_block_given_p()) { + rb_raise(rb_eArgError, "block not given."); + } + + VALUE block = Qnil; + rb_scan_args(argc, argv, "0&", &block); + try { + cvSetMouseCallback(GET_WINDOW_NAME(self), on_mouse, (void*)block); + } + catch (cv::Exception& e) { + raise_cverror(e); + } + + rb_ary_push(WINDOW(self)->blocks, block); + return block; +} + +void +init_ruby_class() +{ +#if 0 + // For documentation using YARD + VALUE opencv = rb_define_module("OpenCV"); + VALUE GUI = rb_define_module_under(opencv, "GUI"); +#endif + + if (rb_klass) + return; + /* + * opencv = rb_define_module("OpenCV"); + * GUI = rb_define_module_under(opencv, "GUI"); + * + * note: this comment is used by rdoc. + */ + VALUE GUI = rb_module_GUI(); + rb_klass = rb_define_class_under(GUI, "Window", rb_cObject); + rb_define_alloc_func(rb_klass, rb_allocate); + rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); + rb_define_method(rb_klass, "alive?", RUBY_METHOD_FUNC(rb_alive_q), 0); + rb_define_method(rb_klass, "destroy", RUBY_METHOD_FUNC(rb_destroy), 0); + rb_define_singleton_method(rb_klass, "destroy_all", RUBY_METHOD_FUNC(rb_destroy_all), 0); + rb_define_method(rb_klass, "resize", RUBY_METHOD_FUNC(rb_resize), -1); + rb_define_method(rb_klass, "move", RUBY_METHOD_FUNC(rb_move), -1); + rb_define_method(rb_klass, "show_image", RUBY_METHOD_FUNC(rb_show_image), 1); + rb_define_alias(rb_klass, "show", "show_image"); + rb_define_method(rb_klass, "set_trackbar", RUBY_METHOD_FUNC(rb_set_trackbar), -1); + rb_define_method(rb_klass, "set_mouse_callback", RUBY_METHOD_FUNC(rb_set_mouse_callback), -1); + rb_define_alias(rb_klass, "on_mouse", "set_mouse_callback"); +} + +__NAMESPACE_END_WINDOW +__NAMESPACE_END_GUI +__NAMESPACE_END_OPENCV + diff --git a/ext/window.h b/ext/opencv/window.h similarity index 62% rename from ext/window.h rename to ext/opencv/window.h index 6b72cbeb..93cf20cf 100644 --- a/ext/window.h +++ b/ext/opencv/window.h @@ -7,8 +7,6 @@ Copyright (C) 2005-2006 Masakazu Yonekura ************************************************************/ -#ifdef HAVE_CALLBACK_H - #ifndef RUBY_OPENCV_GUI_H #include "gui.h" #endif @@ -17,35 +15,48 @@ #define RUBY_OPENCV_GUI_WINDOW_H #include "opencv.h" -#define __NAMESPACE_BEGIN_WINDOW namespace cWindow{ +#define __NAMESPACE_BEGIN_WINDOW namespace cWindow { #define __NAMESPACE_END_WINDOW } __NAMESPACE_BEGIN_OPENCV __NAMESPACE_BEGIN_GUI + +typedef struct Window { + VALUE name; + VALUE image; + VALUE trackbars; + VALUE blocks; +} Window; + __NAMESPACE_BEGIN_WINDOW -void define_ruby_class(); +void init_ruby_class(); VALUE rb_allocate(VALUE klass); -void mark(void *ptr); -VALUE each_protect(VALUE key, VALUE value); -//VALUE each_protect(void *key, VALUE value); -void free(void *ptr); - -VALUE rb_aref(VALUE klass, VALUE name); -VALUE rb_initialize(int argc, VALUE *argv, VALUE self); +void window_mark(void *ptr); +void window_free(void *ptr); VALUE rb_alive_q(VALUE self); +VALUE rb_initialize(int argc, VALUE *argv, VALUE self); VALUE rb_destroy(VALUE self); VALUE rb_destroy_all(VALUE klass); VALUE rb_resize(int argc, VALUE *argv, VALUE self); VALUE rb_move(int argc, VALUE *argv, VALUE self); -VALUE rb_show_image(VALUE self, VALUE image); +VALUE rb_show_image(VALUE self, VALUE img); VALUE rb_set_trackbar(int argc, VALUE *argv, VALUE self); -VALUE rb_set_mouse_callback(VALUE self); +VALUE rb_set_mouse_callback(int argc, VALUE* argv, VALUE self); + +inline Window* +WINDOW(VALUE object) { + Window *ptr; + Data_Get_Struct(object, Window, ptr); + return ptr; +} -void trackbar_callback(VALUE block, va_alist ap); -void mouse_callback(VALUE block, va_alist ap); +inline const char* +GET_WINDOW_NAME(VALUE object) { + return StringValueCStr(WINDOW(object)->name); +} __NAMESPACE_END_WINDOW __NAMESPACE_END_GUI @@ -53,4 +64,3 @@ __NAMESPACE_END_OPENCV #endif // RUBY_OPENCV_GUI_WINDOW_H -#endif // HAVE_CALLBACK_H diff --git a/ext/point3dset.cpp b/ext/point3dset.cpp deleted file mode 100644 index fe078f63..00000000 --- a/ext/point3dset.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************ - - point3dset.cpp - - - $Author: lsxi $ - - Copyright (C) 2008 Masakazu Yonekura - -************************************************************/ -#include"point3dset.h" -/* - * Document-class: OpenCV::Point3DSet - */ - -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_POINT3D_SET - -VALUE module; - -VALUE -rb_module() -{ - return module; -} - -void -define_ruby_module() -{ - if(module) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - module = rb_define_module_under(opencv, "Point3DSet"); -} - -__NAMESPACE_END_POINT3D_SET -__NAMESPACE_END_OPENCV diff --git a/ext/point3dset.h b/ext/point3dset.h deleted file mode 100644 index 964cdc34..00000000 --- a/ext/point3dset.h +++ /dev/null @@ -1,31 +0,0 @@ -/************************************************************ - - point3dset.h - - - $Author: lsxi $ - - Copyright (C) 2008 Masakazu Yonekura - -************************************************************/ -#ifndef RUBY_OPENCV_POINT3DSET_H -#define RUBY_OPENCV_POINT3DSET_H - -#define __NAMESPACE_BEGIN_POINT3D_SET namespace mPoint3DSet{ -#define __NAMESPACE_END_POINT3D_SET } - -#include"opencv.h" - -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_POINT3D_SET - -VALUE rb_module(); - -void define_ruby_module(); - -__NAMESPACE_END_POINT3D_SET - -#define POINT3D_SET_P(object) rb_obj_is_kind_of(object, cCvSeq::rb_class()) && CV_IS_SEQ_POINT3D_SET(CVSEQ(object)) - -__NAMESPACE_END_OPENCV - -#endif // RUBY_OPENCV_POINT3DSET_H diff --git a/ext/pointset.cpp b/ext/pointset.cpp deleted file mode 100644 index e8072826..00000000 --- a/ext/pointset.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/************************************************************ - - pointset.cpp - - - $Author: lsxi $ - - Copyright (C) 2005-2006 Masakazu Yonekura - -************************************************************/ -#include"pointset.h" -/* - * Document-class: OpenCV::PointSet - */ - -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_POINT_SET - -VALUE module; - -VALUE -rb_module() -{ - return module; -} - -void -define_ruby_module() -{ - if(module) - return; - /* - * opencv = rb_define_module("OpenCV"); - * - * note: this comment is used by rdoc. - */ - VALUE opencv = rb_module_opencv(); - module = rb_define_module_under(opencv, "PointSet"); - rb_define_method(module, "contour_area", RUBY_METHOD_FUNC(rb_contour_area), -1); - rb_define_method(module, "fit_ellipse", RUBY_METHOD_FUNC(rb_fit_ellipse), 0); - - rb_define_method(module, "convex_hull", RUBY_METHOD_FUNC(rb_convex_hull), -1); - rb_define_method(module, "check_contour_convexity", RUBY_METHOD_FUNC(rb_check_contour_convexity), 0); - rb_define_alias(module, "convexity?", "check_contour_convexity"); - rb_define_method(module, "convexity_defects", RUBY_METHOD_FUNC(rb_convexity_defects), -1); - rb_define_method(module, "min_area_rect", RUBY_METHOD_FUNC(rb_min_area_rect), 0); - rb_define_method(module, "min_enclosing_circle", RUBY_METHOD_FUNC(rb_min_enclosing_circle), 0); -} - -VALUE -rb_extend_object(VALUE self, VALUE object) -{ - CvSeq *seq = 0; - if(!rb_obj_is_kind_of(object, cCvSeq::rb_class())) - rb_raise(rb_eTypeError, "object is not %s.\n", rb_class2name(cCvSeq::rb_class())); - - if(!CV_IS_SEQ(seq)) - rb_raise(rb_eTypeError, "object is not sequence."); - return rb_call_super(1, &object); -} - -/* - * call-seq: - * contour_area -> float - * - * Calculates area of the whole contour or contour section. - * - * note: Orientation of the contour affects the area sign, thus the method may return negative result. - */ -VALUE -rb_contour_area(int argc, VALUE *argv, VALUE self) -{ - VALUE slice; - rb_scan_args(argc, argv, "01", &slice); - return rb_float_new(cvContourArea(CVARR(self), NIL_P(slice) ? CV_WHOLE_SEQ : VALUE_TO_CVSLICE(slice))); -} - -/* - * call-seq: - * fit_ellipse -> cvbox2d - * - * Return fits ellipse to set of 2D points. - */ -VALUE -rb_fit_ellipse(VALUE self) -{ - return cCvBox2D::new_object(cvFitEllipse2(CVARR(self))); -} - -/* - * call-seq: - * convex_hull([reverse = fasle]) -> cvcontour - * - * Finds convex hull of 2D point set using Sklansky's algorithm. - * - * reverse is desired orientation of convex hull. - * If reverse is false mean clockwise, otherwise counter clockwise. - */ -VALUE -rb_convex_hull(int argc, VALUE *argv, VALUE self) -{ - VALUE reverse, storage; - rb_scan_args(argc, argv, "01", &reverse); - storage = cCvMemStorage::new_object(); - CvSeq *hull = cvConvexHull2(CVSEQ(self), CVMEMSTORAGE(storage), TRUE_OR_FALSE(reverse, 0) ? CV_COUNTER_CLOCKWISE : CV_CLOCKWISE, 1); - if(CV_IS_SEQ_HOLE(CVSEQ(self))) - hull->flags |= CV_SEQ_FLAG_HOLE; - return cCvSeq::new_sequence(cCvContour::rb_class(), hull, cCvPoint::rb_class(), storage); -} - -/* - * call-seq: - * check_contour_convexity -> true or false - * - * Tests whether the input contour is convex or not. The contour must be simple, i.e. without self-intersections. - */ -VALUE -rb_check_contour_convexity(VALUE self) -{ - return cvCheckContourConvexity(CVARR(self)) ? Qtrue : Qfalse; -} - -/* - * call-seq: - * convexity_defects([reverse = false]) -> cvseq(include CvConvexityDefect) - * - * Finds convexity defects of contour. - */ -VALUE -rb_convexity_defects(int argc, VALUE *argv, VALUE self) -{ - VALUE reverse, storage; - rb_scan_args(argc, argv, "01", &reverse); - storage = cCvMemStorage::new_object(); - CvSeq *hull, *convex; - hull = cvConvexHull2(CVSEQ(self), CVMEMSTORAGE(storage), TRUE_OR_FALSE(reverse, 0) ? CV_COUNTER_CLOCKWISE : CV_CLOCKWISE, 0); - convex = cvConvexityDefects(CVSEQ(self), hull, CVMEMSTORAGE(storage)); - return cCvSeq::new_sequence(cCvSeq::rb_class(), convex, cCvConvexityDefect::rb_class(), storage); -} - -/* - * call-seq: - * min_area_rect -> cvbox2d - * - * Finds circumscribed rectangle of minimal area for given 2D point set. - */ -VALUE -rb_min_area_rect(VALUE self) -{ - VALUE storage = cCvMemStorage::new_object(); - return cCvBox2D::new_object(cvMinAreaRect2(CVARR(self), CVMEMSTORAGE(storage))); -} - -/* - * call-seq: - * min_enclosing_circle -> cvcircle32f - * - * Finds circumscribed circle of minimal area for given 2D point set. - */ -VALUE -rb_min_enclosing_circle(VALUE self) -{ - VALUE circle = cCvCircle32f::rb_allocate(cCvCircle32f::rb_class()); - cvMinEnclosingCircle(CVARR(self), &CVCIRCLE32F(circle)->center, &CVCIRCLE32F(circle)->radius); - return circle; -} - -VALUE -rb_calc_pgh(VALUE self) -{ - /* not yet */ - return Qnil; -} - -__NAMESPACE_END_POINT_SET - -int -CVPOINTS_FROM_POINT_SET(VALUE object, CvPoint **pointset) -{ - VALUE storage; - CvSeq *seq = 0; - CvPoint2D32f p32; - if(rb_obj_is_kind_of(object, cCvSeq::rb_class())){ - if(CV_IS_SEQ_POINT_SET(CVSEQ(object))){ - *pointset = (CvPoint*)cvCvtSeqToArray(CVSEQ(object), cvAlloc(CVSEQ(object)->total * CVSEQ(object)->elem_size)); - return CVSEQ(object)->total; - }else{ - rb_raise(rb_eTypeError, "sequence is not contain %s or %s.", rb_class2name(cCvPoint::rb_class()), rb_class2name(cCvPoint2D32f::rb_class())); - } - }else if(rb_obj_is_kind_of(object, cCvMat::rb_class())){ - /* to do */ - rb_raise(rb_eNotImpError, "CvMat to CvSeq conversion not implemented."); - }else if(rb_obj_is_kind_of(object, rb_cArray)){ - *pointset = (CvPoint*)cvAlloc(RARRAY(object)->len * sizeof(CvPoint)); - for(int i = 0; i < RARRAY(object)->len; i++){ - (*pointset)[i].x = NUM2INT(rb_funcall(rb_ary_entry(object, i), rb_intern("x"), 0)); - (*pointset)[i].y = NUM2INT(rb_funcall(rb_ary_entry(object, i), rb_intern("y"), 0)); - } - return RARRAY(object)->len; - }else{ - rb_raise(rb_eTypeError, "Can't convert CvSeq(PointSet)."); - } -} - -CvSeq* -VALUE_TO_POINT_SET(VALUE object) -{ - CvSeq *seq = 0; - VALUE tmp, storage; - int length; - CvPoint2D32f p32; - if(rb_obj_is_kind_of(object, cCvSeq::rb_class())){ - seq = CVSEQ(object); - if(CV_IS_SEQ_POINT_SET(seq)){ - return seq; - }else{ - rb_raise(rb_eTypeError, "sequence is not contain %s or %s.", rb_class2name(cCvPoint::rb_class()), rb_class2name(cCvPoint2D32f::rb_class())); - } - }else if(rb_obj_is_kind_of(object, cCvMat::rb_class())){ - /* to do */ - rb_raise(rb_eNotImpError, "CvMat to CvSeq conversion not implemented."); - }else if(rb_obj_is_kind_of(object, rb_cArray)){ - //pointset = cCvSeq::new_sequence(cCvSeq::rb_class(), ) - length = RARRAY(object)->len; - storage = cCvMemStorage::new_object(); - seq = cvCreateSeq(CV_SEQ_POINT_SET, sizeof(CvSeq), sizeof(CvPoint), CVMEMSTORAGE(storage)); - for(int i = 0; i < RARRAY(object)->len; i++){ - p32.x = NUM2DBL(rb_funcall(rb_ary_entry(object, i), rb_intern("x"), 0)); - p32.y = NUM2DBL(rb_funcall(rb_ary_entry(object, i), rb_intern("y"), 0)); - cvSeqPush(seq, &p32); - } - tmp = cCvSeq::new_sequence(cCvSeq::rb_class(), seq, cCvPoint2D32f::rb_class(), storage); - return seq; - }else{ - rb_raise(rb_eTypeError, "Can't convert CvSeq(PointSet)."); - } -} - -__NAMESPACE_END_OPENCV diff --git a/ext/window.cpp b/ext/window.cpp deleted file mode 100644 index cff0ae86..00000000 --- a/ext/window.cpp +++ /dev/null @@ -1,368 +0,0 @@ -/************************************************************ - - window.cpp - - - $Author: lsxi $ - - Copyright (C) 2005-2006 Masakazu Yonekura - -************************************************************/ -#ifdef HAVE_CALLBACK_H - -#include "window.h" -/* - * Document-class: OpenCV::GUI::Window - * - * Simple Window wedget. Window can show image(CvMat/IplImage). - * - * view image sample: - * image = OpenCV::IplImage::load("opencv.bmp") #=> load image - * window = OpenCV::GUI::Window.new("simple viewer")#=> create new window named "simaple viewer" - * window.show(image) #=> show image - */ -__NAMESPACE_BEGIN_OPENCV -__NAMESPACE_BEGIN_GUI -__NAMESPACE_BEGIN_WINDOW - -const char* -GET_WINDOW_NAME(VALUE object) -{ - void *handle = DATA_PTR(object); - if (!handle) - rb_raise(rb_eStandardError, "window handle error"); - const char *window_name = cvGetWindowName(handle); - return window_name; -} - -st_table *windows = st_init_numtable(); - -VALUE rb_klass; - -VALUE -rb_class() -{ - return rb_klass; -} - -void -define_ruby_class() -{ - if (rb_klass) - return; - /* - * opencv = rb_define_module("OpenCV"); - * GUI = rb_define_module_under(opencv, "GUI"); - * - * note: this comment is used by rdoc. - */ - VALUE GUI = rb_module_GUI(); - rb_klass = rb_define_class_under(GUI, "Window", rb_cObject); - rb_define_singleton_method(rb_klass, "[]", RUBY_METHOD_FUNC(rb_aref), 1); - rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1); - rb_define_method(rb_klass, "alive?", RUBY_METHOD_FUNC(rb_alive_q), 0); - rb_define_method(rb_klass, "destroy", RUBY_METHOD_FUNC(rb_destroy), 0); - rb_define_singleton_method(rb_klass, "destroy_all", RUBY_METHOD_FUNC(rb_destroy_all), 0); - rb_define_method(rb_klass, "resize", RUBY_METHOD_FUNC(rb_resize), -1); - rb_define_method(rb_klass, "move", RUBY_METHOD_FUNC(rb_move), -1); - rb_define_method(rb_klass, "show_image", RUBY_METHOD_FUNC(rb_show_image), 1); - rb_define_alias(rb_klass, "show", "show_image"); - rb_define_method(rb_klass, "set_trackbar", RUBY_METHOD_FUNC(rb_set_trackbar), -1); - rb_define_method(rb_klass, "set_mouse_callback", RUBY_METHOD_FUNC(rb_set_mouse_callback), 0); - rb_define_alias(rb_klass, "on_mouse", "set_mouse_callback"); -} - -VALUE -rb_allocate(VALUE klass) -{ - return Data_Wrap_Struct(klass, mark, free, 0); -} - -void -mark(void *ptr) -{ - st_table *holder; - if (st_lookup(windows, (st_data_t)ptr, (st_data_t*)&holder)) { - st_foreach(holder, (int (*)(ANYARGS))each_protect, 0); - } -} - -VALUE -each_protect(VALUE key, VALUE value) -{ - rb_gc_mark(value); - return ST_CONTINUE; -} - -void -free(void *ptr) -{ - cvFree(&ptr); -} - -/* - * call-seq: - * [name] - * - * Return window named name if exist, otherwise nil. - */ -VALUE -rb_aref(VALUE klass, VALUE name) -{ - VALUE window; - Check_Type(name, T_STRING); - void *handle = cvGetWindowHandle(StringValueCStr(name)); - st_table *holder; - if (st_lookup(windows, (st_data_t)handle, (st_data_t*)&holder) && - st_lookup(holder, 0, (st_data_t*)&window)) { - return window; - } - return Qnil; -} - -/* - * call-seq: - * new(name[,autosize]) - * - * Create new window named name. - * If autoresize is true(default), window size automatically resize when image given. - */ -VALUE -rb_initialize(int argc, VALUE *argv, VALUE self) -{ - VALUE name, autosize; - rb_scan_args(argc, argv, "11", &name, &autosize); - Check_Type(name, T_STRING); - int mode; - if (argc < 2) - mode = CV_WINDOW_AUTOSIZE; - else{ - switch (TYPE(autosize)) { - case T_TRUE: - mode = CV_WINDOW_AUTOSIZE; - break; - case T_FALSE: - mode = 0; - break; - default: - rb_raise(rb_eTypeError, "argument 2 (auto-size) should be true or false."); - } - } - cvNamedWindow(StringValueCStr(name), mode); - void *handle = cvGetWindowHandle(StringValueCStr(name)); - if (st_lookup(windows, (st_data_t)handle, 0)) { - rb_raise(rb_eStandardError, "window name should be unique."); - } - DATA_PTR(self) = handle; - st_table *holder = st_init_numtable(); - st_insert(holder, (st_data_t)0, (st_data_t)self); - st_insert(windows, (st_data_t)handle, (st_data_t)holder); - return self; -} - -/* - * Return alive status of window. Return true if alive, otherwise return false. - */ -VALUE -rb_alive_q(VALUE self) -{ - if (st_lookup(windows, (st_data_t)DATA_PTR(self), 0)) { - return Qtrue; - } - return Qfalse; -} - -/* - * Destroys a window. alive status of window be false. - */ -VALUE -rb_destroy(VALUE self) -{ - void *handle = DATA_PTR(self); - st_table *holder; - if (st_delete(windows, (st_data_t*)&handle, (st_data_t*)&holder)) { - st_free_table(holder); - } - cvDestroyWindow(GET_WINDOW_NAME(self)); - return self; -} - -/* - * Destorys all the windows. - */ -VALUE -rb_destroy_all(VALUE klass) -{ - st_free_table(windows); - windows = st_init_numtable(); - cvDestroyAllWindows(); - return Qnil; -} - -/* - * call-seq: - * resize(size) - * resize(width, height) - * - * Set window size. - */ -VALUE -rb_resize(int argc, VALUE *argv, VALUE self) -{ - CvSize size; - switch (argc) { - case 1: - size = VALUE_TO_CVSIZE(argv[0]); - break; - case 2: - size = cvSize(FIX2INT(argv[0]), FIX2INT(argv[1])); - break; - default: - rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)"); - } - cvResizeWindow(GET_WINDOW_NAME(self), size.width, size.height); - return self; -} - -/* - * call-seq: - * move(point) - * move(x, y) - * - * Set window position. - */ -VALUE -rb_move(int argc, VALUE *argv, VALUE self) -{ - CvPoint point; - switch (argc) { - case 1: - point = VALUE_TO_CVPOINT(argv[0]); - break; - case 2: - point = cvPoint(FIX2INT(argv[0]), FIX2INT(argv[1])); - break; - default: - rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)"); - } - cvMoveWindow(GET_WINDOW_NAME(self), point.x, point.y); - return self; -} - -/* - * call-seq: - * show_image(image) - * - * Show the image. If the window was created with autosize = true then the image is shown - * with its original size, otherwize the image is scaled to fit the window. - */ -VALUE -rb_show_image(VALUE self, VALUE image) -{ - if (!rb_obj_is_kind_of(image, cCvMat::rb_class())) { - rb_raise(rb_eTypeError, "argument should be %s.", rb_class2name(cCvMat::rb_class())); - } - cvShowImage(GET_WINDOW_NAME(self), CVARR(image)); - st_table *holder; - if (st_lookup(windows, (st_data_t)DATA_PTR(self), (st_data_t*)&holder)) { - st_insert(holder, cCvMat::rb_class(), image); - return self; - }else - rb_raise(rb_eFatal, "invalid window operation."); - return self; -} - -/* - * call-seq: - * set_trackbar(trackbar) - * set_trackbar(name,maxval[,val],&block) - * set_trackbar(name,maxval[,val]){|value| ... } - * - * Create Trackbar on this window. Return new Trackbar. - * see Trackbar.new - */ -VALUE -rb_set_trackbar(int argc, VALUE *argv, VALUE self) -{ - VALUE instance; - if (argc == 1 && rb_obj_is_kind_of(argv[0], cTrackbar::rb_class())) { - instance = argv[0]; - }else{ - instance = cTrackbar::rb_initialize(argc, argv, cTrackbar::rb_allocate(cTrackbar::rb_class())); - } - Trackbar *trackbar = TRACKBAR(instance); - void *callback = (void *)alloc_callback(&trackbar_callback, trackbar->block); - cvCreateTrackbar(trackbar->name, GET_WINDOW_NAME(self), &trackbar->val, trackbar->maxval, (CvTrackbarCallback)callback); - st_table *holder; - if (st_lookup(windows, (st_data_t)DATA_PTR(self), (st_data_t*)&holder)) { - st_insert(holder, (st_data_t)&trackbar->name, (st_data_t)instance); - } - return instance; -} - -/* - * call-seq: - * set_mouse_callback(&block) - * set_mouse_callback{|| ... } - * - * Set mouse callback. - * When the mouse is operated on the window, block will be called. - * Return Proc object. - * block given mouse event object, see GUI::Window::MouseEvent - * - * e.g. display mouse event on console. - * window = OpenCV::GUI::Window.new "sample window" - * image = OpenCV::IplImage::load "sample.png" - * window.show(image) - * window.set_mouse_callback{|mouse| - * e = "#{mouse.x}, #{mouse.y} : #{mouse.event} : " - * e << "" if mouse.left_button? - * e << "" if mouse.right_button? - * e << "" if mouse.middle_button? - * e << "[CTRL]" if mouse.ctrl_key? - * e << "[SHIFT]" if mouse.shift_key? - * e << "[ALT]" if mouse.alt_key? - * puts e - * } - * OpenCV::GUI::wait_key - */ -VALUE -rb_set_mouse_callback(VALUE self) -{ - VALUE block = rb_block_given_p() ? rb_block_proc() : 0; - if (!block) {rb_raise(rb_eArgError, "block not given.");} - void *callback = (void *)alloc_callback(&mouse_callback, block); - cvSetMouseCallback(GET_WINDOW_NAME(self), (CvMouseCallback)callback); - st_table *holder; - if (st_lookup(windows, (st_data_t)DATA_PTR(self), (st_data_t*)&holder)) { - st_insert(holder, rb_cProc, block); - }else{ - rb_raise(rb_eStandardError, "window is destroied."); - } - return block; -} - -void -trackbar_callback(VALUE block, va_alist ap) -{ - va_start_void(ap); - rb_funcall(block, rb_intern("call"), 1, INT2FIX(va_arg_int(ap))); - va_return_void(ap); -} - -void -mouse_callback(VALUE block, va_alist ap) -{ - va_start_void(ap); - //VALUE ary = rb_ary_new2(4); - //for (int i = 0; i < 4; i++) - // rb_ary_store(ary, i, INT2FIX(va_arg_int(ap))); - //rb_apply(block, rb_intern("call"), ary); - rb_funcall(block, rb_intern("call"), 1, cMouseEvent::new_object(va_arg_int(ap),va_arg_int(ap),va_arg_int(ap),va_arg_int(ap))); - va_return_void(ap); -} - -__NAMESPACE_END_WINDOW -__NAMESPACE_END_GUI -__NAMESPACE_END_OPENCV - -#endif // HAVE_CALLBACK_H diff --git a/images/face_detect_from_lena.jpg b/images/face_detect_from_lena.jpg deleted file mode 100644 index eabd54e9..00000000 Binary files a/images/face_detect_from_lena.jpg and /dev/null differ diff --git a/install-ruby-opencv-with-rubyinstaller-on-windows.md b/install-ruby-opencv-with-rubyinstaller-on-windows.md new file mode 100644 index 00000000..7afcb098 --- /dev/null +++ b/install-ruby-opencv-with-rubyinstaller-on-windows.md @@ -0,0 +1,83 @@ +# Install ruby-opencv with RubyInstaller on Windows + +This document shows how to install ruby-opencv with RubyInstaller on Windows. + +Official OpenCV binary for MinGW32 is no longer distributed, so when you use ruby-opencv with RubyInstaller, you should build OpenCV yourself using Devkit. + + +## Requirement +- Windows 10 64bit +- [Ruby 2.3.0p0 x64-mingw32 on RubyInstaller](http://rubyinstaller.org/) +- [Devkit (DevKit-mingw64-64-4.7.2-20130224-1432-sfx.exe)](https://rubyinstaller.org/downloads/archives/) +- [OpenCV 2.4.13](https://sourceforge.net/projects/opencvlibrary/) +- [CMake 3.6.0 x64](https://cmake.org/) + + +## How to install OpenCV and ruby-opencv +### Download and extract OpenCV + +Download OpenCV library from https://sourceforge.net/projects/opencvlibrary/ and extract it. + + +### Create OpenCV Makefile with CMake + +Open ```cmd.exe``` and run the following commands. + +``` +D:\>set DEVKIT_PATH=D:/local/devkit +D:\>set SOURCE_PATH=D:/work/opencv-2.4.13/sources +D:\>set OPENCV_INSTALL_PATH=D:/opencv-2.4.13 +D:\>cmake %SOURCE_PATH% -G"MinGW Makefiles" -DCMAKE_INSTALL_PREFIX=%OPENCV_INSTALL_PATH% -DCMAKE_MAKE_PROGRAM=%DEVKIT_PATH%/mingw/bin/mingw32-make.exe -DCMAKE_C_COMPILER=%DEVKIT_PATH%/mingw/bin/gcc.exe -DCMAKE_CXX_COMPILER=%DEVKIT_PATH%/mingw/bin/g++.exe -DBUILD_PERF_TESTS=OFF +``` + +In this document, I assume that the Devkit is installed to ```D:/local/devkit```, the OpenCV library is extracted to ```D:/work/opencv-2.4.13``` and its source directory is ```D:/work/opencv-2.4.13/sources```, and the output will be installed in ```D:/opencv-2.4.13```. + +Note that ```D:\>``` is a prompt of ```cmd.exe```, so you should not input it. + + +### Build OpenCV with DevKit + +Run the following commands in ```cmd.exe```. + +``` +D:\>%DEVKIT_PATH%/mingw/bin/mingw32-make.exe +D:\>%DEVKIT_PATH%/mingw/bin/mingw32-make.exe install +``` + + +### Install ruby-opencv + +Run the following commands in ```cmd.exe```. + +``` +D:\>path %OPENCV_INSTALL_PATH%\x64\mingw\bin;%DEVKIT_PATH%\mingw\bin;%PATH% +D:\>gem install ruby-opencv -- --with-opencv-include=%OPENCV_INSTALL_PATH%/include --with-opencv-lib=%OPENCV_INSTALL_PATH%/x64/mingw/lib +``` + +And try to use ruby-opencv. + +``` +D:\>irb +irb(main):001:0> require 'opencv' +=> true +irb(main):002:0> OpenCV::CV_VERSION +=> "2.4.13" +``` + +Note that the paths ```%OPENCV_INSTALL_PATH%\x64\mingw\bin``` and ```%DEVKIT_PATH%\mingw\bin``` must **ALWAYS** be set when using ```ruby-opencv```, or you may get the following error. + +``` +D:\>irb +irb(main):001:0> require 'opencv' +LoadError: 126: The specified module could not be found. - D:/local/ruby/lib/ruby/gems/2.3.0/gems/ruby-opencv-0.0.17/lib/opencv.so + from D:/local/ruby/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:133:in `require' + from D:/local/ruby/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:133:in `rescue in require' + from D:/local/ruby/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:40:in `require' + from D:/local/ruby/lib/ruby/gems/2.3.0/gems/ruby-opencv-0.0.17/lib/opencv.rb:8:in `rescue in ' + from D:/local/ruby/lib/ruby/gems/2.3.0/gems/ruby-opencv-0.0.17/lib/opencv.rb:5:in `' + from D:/local/ruby/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:133:in `require' + from D:/local/ruby/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:133:in `rescue in require' + from D:/local/ruby/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:40:in `require' + from (irb):1 + from D:/local/ruby/bin/irb.cmd:19:in `
' +``` diff --git a/lib/opencv.rb b/lib/opencv.rb index 61058dec..d6ba2e1d 100755 --- a/lib/opencv.rb +++ b/lib/opencv.rb @@ -1,3 +1,12 @@ -require (File.dirname(__FILE__) + '/version') -require 'opencv.so' +require (File.dirname(__FILE__) + '/opencv/version') +if RUBY_PLATFORM =~ /mingw|mswin/ + major, minor, subminor = RUBY_VERSION.split('.') + begin + require "#{major}.#{minor}/opencv.so" + rescue LoadError + require 'opencv.so' + end +else + require 'opencv.so' +end diff --git a/lib/opencv/psyched_yaml.rb b/lib/opencv/psyched_yaml.rb new file mode 100644 index 00000000..5ee5d5f2 --- /dev/null +++ b/lib/opencv/psyched_yaml.rb @@ -0,0 +1,22 @@ +# -*- mode: ruby; coding: utf-8 -*- +# Psych loader for avoiding loading problem +# (borrowed from Bundler 1.1.rc.7 https://github.com/carlhuda/bundler/blob/v1.1.rc.7/lib/bundler/psyched_yaml.rb ) +# +# See: https://github.com/ruby-opencv/ruby-opencv/pull/6 + +# Psych could be a gem +begin + gem 'psych' +rescue Gem::LoadError +end if defined?(Gem) + +# Psych could be a stdlib +begin + # it's too late if Syck is already loaded + require 'psych' unless defined?(Syck) +rescue LoadError +end + +# Psych might NOT EXIST AT ALL +require 'yaml' + diff --git a/lib/opencv/version.rb b/lib/opencv/version.rb new file mode 100755 index 00000000..5561b306 --- /dev/null +++ b/lib/opencv/version.rb @@ -0,0 +1,3 @@ +module OpenCV + VERSION = '0.0.18' +end diff --git a/lib/version.rb b/lib/version.rb deleted file mode 100755 index 54f73d40..00000000 --- a/lib/version.rb +++ /dev/null @@ -1,3 +0,0 @@ -module OpenCV - VERSION = '0.0.6' -end diff --git a/metadata b/metadata deleted file mode 100644 index c005e75a..00000000 --- a/metadata +++ /dev/null @@ -1,191 +0,0 @@ ---- !ruby/object:Gem::Specification -name: opencv -version: !ruby/object:Gem::Version - version: 0.0.6 -platform: ruby -authors: -- Masakazu Yonekura -- lsxi -autorequire: -bindir: bin -cert_chain: [] - -date: 2008-06-29 00:00:00 +09:00 -default_executable: -dependencies: -- !ruby/object:Gem::Dependency - name: hoe - version_requirement: - version_requirements: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: "0" - version: -- !ruby/object:Gem::Dependency - name: hoe - version_requirement: - version_requirements: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: 1.6.0 - version: -description: OpenCV wrapper for Ruby -email: -- masakazu.yonekura@gmail.com -executables: [] - -extensions: -- ext/extconf.rb -extra_rdoc_files: -- History.txt -- Manifest.txt -- README.txt -- License.txt -files: -- History.txt -- Manifest.txt -- README.txt -- License.txt -- Rakefile -- examples/convexhull.rb -- examples/face_detect.rb -- examples/houghcircle.rb -- examples/inpaint.png -- examples/inpaint.rb -- examples/paint.rb -- examples/snake.rb -- examples/stuff.jpg -- ext/curve.cpp -- ext/curve.h -- ext/cvavgcomp.cpp -- ext/cvavgcomp.h -- ext/cvbox2d.cpp -- ext/cvbox2d.h -- ext/cvcapture.cpp -- ext/cvcapture.h -- ext/cvchain.cpp -- ext/cvchain.h -- ext/cvchaincode.cpp -- ext/cvchaincode.h -- ext/cvcircle32f.cpp -- ext/cvcircle32f.h -- ext/cvcondensation.cpp -- ext/cvcondensation.h -- ext/cvconnectedcomp.cpp -- ext/cvconnectedcomp.h -- ext/cvcontour.cpp -- ext/cvcontour.h -- ext/cvcontourtree.cpp -- ext/cvcontourtree.h -- ext/cvconvexitydefect.cpp -- ext/cvconvexitydefect.h -- ext/cverror.cpp -- ext/cverror.h -- ext/cvfont.cpp -- ext/cvfont.h -- ext/cvhaarclassifiercascade.cpp -- ext/cvhaarclassifiercascade.h -- ext/cvhistogram.cpp -- ext/cvhistogram.h -- ext/cvindex.cpp -- ext/cvindex.h -- ext/cvline.cpp -- ext/cvline.h -- ext/cvmat.cpp -- ext/cvmat.h -- ext/cvmatnd.cpp -- ext/cvmatnd.h -- ext/cvmemstorage.cpp -- ext/cvmemstorage.h -- ext/cvmoments.cpp -- ext/cvmoments.h -- ext/cvpoint.cpp -- ext/cvpoint.h -- ext/cvpoint2d32f.cpp -- ext/cvpoint2d32f.h -- ext/cvpoint3d32f.cpp -- ext/cvpoint3d32f.h -- ext/cvrect.cpp -- ext/cvrect.h -- ext/cvscalar.cpp -- ext/cvscalar.h -- ext/cvseq.cpp -- ext/cvseq.h -- ext/cvset.cpp -- ext/cvset.h -- ext/cvsize.cpp -- ext/cvsize.h -- ext/cvsize2d32f.cpp -- ext/cvsize2d32f.h -- ext/cvslice.cpp -- ext/cvslice.h -- ext/cvsparsemat.cpp -- ext/cvsparsemat.h -- ext/cvtermcriteria.cpp -- ext/cvtermcriteria.h -- ext/cvtwopoints.cpp -- ext/cvtwopoints.h -- ext/cvvector.cpp -- ext/cvvector.h -- ext/cvvideowriter.cpp -- ext/cvvideowriter.h -- ext/extconf.rb -- ext/gui.cpp -- ext/gui.h -- ext/iplconvkernel.cpp -- ext/iplconvkernel.h -- ext/iplimage.cpp -- ext/iplimage.h -- ext/mouseevent.cpp -- ext/mouseevent.h -- ext/opencv.cpp -- ext/opencv.h -- ext/point3dset.cpp -- ext/point3dset.h -- ext/pointset.cpp -- ext/pointset.h -- ext/trackbar.cpp -- ext/trackbar.h -- ext/window.cpp -- ext/window.h -- images/CvMat_sobel.png -- images/CvMat_sub_rect.png -- images/CvSeq_relationmap.png -- images/face_detect_from_lena.jpg -- lib/opencv.rb -- lib/version.rb -- setup/setup.cygwin.rb -- setup/setup.mingw.rb -- setup/setup.mswin32.rb -has_rdoc: true -homepage: http://blueruby.mydns.jp/opencv -post_install_message: -rdoc_options: -- --main -- README.txt -require_paths: -- lib -- ext -required_ruby_version: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: "0" - version: -required_rubygems_version: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: "0" - version: -requirements: [] - -rubyforge_project: opencv -rubygems_version: 1.0.1 -signing_key: -specification_version: 2 -summary: OpenCV wrapper for Ruby. -test_files: -- test/test_opencv.rb diff --git a/ruby-opencv.gemspec b/ruby-opencv.gemspec new file mode 100644 index 00000000..600107e7 --- /dev/null +++ b/ruby-opencv.gemspec @@ -0,0 +1,44 @@ +# -*- encoding: utf-8 -*- +# stub: ruby-opencv 0.0.18.20170306223602 ruby lib +# stub: ext/opencv/extconf.rb + +Gem::Specification.new do |s| + s.name = "ruby-opencv".freeze + s.version = "0.0.18.20170306223602" + + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib".freeze] + s.authors = ["lsxi".freeze, "ser1zw".freeze, "pcting".freeze] + s.date = "2017-03-06" + s.description = "ruby-opencv is a wrapper of OpenCV for Ruby. It helps you to write computer vision programs (e.g. detecting faces from pictures) with Ruby.".freeze + s.email = ["masakazu.yonekura@gmail.com".freeze, "azariahsawtikes@gmail.com".freeze, "pcting@gmail.com".freeze] + s.extensions = ["ext/opencv/extconf.rb".freeze] + s.extra_rdoc_files = ["DEVELOPERS_NOTE.md".freeze, "History.txt".freeze, "License.txt".freeze, "Manifest.txt".freeze, "README.md".freeze, "examples/facerec/readme.md".freeze] + s.files = [".gitignore".freeze, ".yardopts".freeze, "DEVELOPERS_NOTE.md".freeze, "Gemfile".freeze, "History.txt".freeze, "License.txt".freeze, "Manifest.txt".freeze, "README.md".freeze, "Rakefile".freeze, "config.yml".freeze, "examples/alpha_blend.rb".freeze, "examples/contours/bitmap-contours-with-labels.png".freeze, "examples/contours/bitmap-contours.png".freeze, "examples/contours/bounding-box-detect-canny.rb".freeze, "examples/contours/contour_retrieval_modes.rb".freeze, "examples/contours/rotated-boxes.jpg".freeze, "examples/convexhull.rb".freeze, "examples/face_detect.rb".freeze, "examples/facerec/create_csv.rb".freeze, "examples/facerec/facerec_eigenfaces.rb".freeze, "examples/facerec/facerec_fisherfaces.rb".freeze, "examples/facerec/facerec_lbph.rb".freeze, "examples/facerec/readme.md".freeze, "examples/find_obj.rb".freeze, "examples/houghcircle.rb".freeze, "examples/images/box.png".freeze, "examples/images/box_in_scene.png".freeze, "examples/images/inpaint.png".freeze, "examples/images/lena-256x256.jpg".freeze, "examples/images/lena-eyes.jpg".freeze, "examples/images/lenna-rotated.jpg".freeze, "examples/images/lenna.jpg".freeze, "examples/images/stuff.jpg".freeze, "examples/images/tiffany.jpg".freeze, "examples/inpaint.rb".freeze, "examples/match_kdtree.rb".freeze, "examples/match_template.rb".freeze, "examples/paint.rb".freeze, "examples/snake.rb".freeze, "ext/opencv/algorithm.cpp".freeze, "ext/opencv/algorithm.h".freeze, "ext/opencv/curve.cpp".freeze, "ext/opencv/curve.h".freeze, "ext/opencv/cvavgcomp.cpp".freeze, "ext/opencv/cvavgcomp.h".freeze, "ext/opencv/cvbox2d.cpp".freeze, "ext/opencv/cvbox2d.h".freeze, "ext/opencv/cvcapture.cpp".freeze, "ext/opencv/cvcapture.h".freeze, "ext/opencv/cvchain.cpp".freeze, "ext/opencv/cvchain.h".freeze, "ext/opencv/cvcircle32f.cpp".freeze, "ext/opencv/cvcircle32f.h".freeze, "ext/opencv/cvconnectedcomp.cpp".freeze, "ext/opencv/cvconnectedcomp.h".freeze, "ext/opencv/cvcontour.cpp".freeze, "ext/opencv/cvcontour.h".freeze, "ext/opencv/cvcontourtree.cpp".freeze, "ext/opencv/cvcontourtree.h".freeze, "ext/opencv/cvconvexitydefect.cpp".freeze, "ext/opencv/cvconvexitydefect.h".freeze, "ext/opencv/cverror.cpp".freeze, "ext/opencv/cverror.h".freeze, "ext/opencv/cvfeaturetree.cpp".freeze, "ext/opencv/cvfeaturetree.h".freeze, "ext/opencv/cvfont.cpp".freeze, "ext/opencv/cvfont.h".freeze, "ext/opencv/cvhaarclassifiercascade.cpp".freeze, "ext/opencv/cvhaarclassifiercascade.h".freeze, "ext/opencv/cvhistogram.cpp".freeze, "ext/opencv/cvhistogram.h".freeze, "ext/opencv/cvhumoments.cpp".freeze, "ext/opencv/cvhumoments.h".freeze, "ext/opencv/cvline.cpp".freeze, "ext/opencv/cvline.h".freeze, "ext/opencv/cvmat.cpp".freeze, "ext/opencv/cvmat.h".freeze, "ext/opencv/cvmemstorage.cpp".freeze, "ext/opencv/cvmemstorage.h".freeze, "ext/opencv/cvmoments.cpp".freeze, "ext/opencv/cvmoments.h".freeze, "ext/opencv/cvpoint.cpp".freeze, "ext/opencv/cvpoint.h".freeze, "ext/opencv/cvpoint2d32f.cpp".freeze, "ext/opencv/cvpoint2d32f.h".freeze, "ext/opencv/cvpoint3d32f.cpp".freeze, "ext/opencv/cvpoint3d32f.h".freeze, "ext/opencv/cvrect.cpp".freeze, "ext/opencv/cvrect.h".freeze, "ext/opencv/cvscalar.cpp".freeze, "ext/opencv/cvscalar.h".freeze, "ext/opencv/cvseq.cpp".freeze, "ext/opencv/cvseq.h".freeze, "ext/opencv/cvsize.cpp".freeze, "ext/opencv/cvsize.h".freeze, "ext/opencv/cvsize2d32f.cpp".freeze, "ext/opencv/cvsize2d32f.h".freeze, "ext/opencv/cvslice.cpp".freeze, "ext/opencv/cvslice.h".freeze, "ext/opencv/cvsurfparams.cpp".freeze, "ext/opencv/cvsurfparams.h".freeze, "ext/opencv/cvsurfpoint.cpp".freeze, "ext/opencv/cvsurfpoint.h".freeze, "ext/opencv/cvtermcriteria.cpp".freeze, "ext/opencv/cvtermcriteria.h".freeze, "ext/opencv/cvtwopoints.cpp".freeze, "ext/opencv/cvtwopoints.h".freeze, "ext/opencv/cvutils.cpp".freeze, "ext/opencv/cvutils.h".freeze, "ext/opencv/cvvideowriter.cpp".freeze, "ext/opencv/cvvideowriter.h".freeze, "ext/opencv/eigenfaces.cpp".freeze, "ext/opencv/eigenfaces.h".freeze, "ext/opencv/extconf.rb".freeze, "ext/opencv/facerecognizer.cpp".freeze, "ext/opencv/facerecognizer.h".freeze, "ext/opencv/fisherfaces.cpp".freeze, "ext/opencv/fisherfaces.h".freeze, "ext/opencv/gui.cpp".freeze, "ext/opencv/gui.h".freeze, "ext/opencv/iplconvkernel.cpp".freeze, "ext/opencv/iplconvkernel.h".freeze, "ext/opencv/iplimage.cpp".freeze, "ext/opencv/iplimage.h".freeze, "ext/opencv/lbph.cpp".freeze, "ext/opencv/lbph.h".freeze, "ext/opencv/mouseevent.cpp".freeze, "ext/opencv/mouseevent.h".freeze, "ext/opencv/opencv.cpp".freeze, "ext/opencv/opencv.h".freeze, "ext/opencv/pointset.cpp".freeze, "ext/opencv/pointset.h".freeze, "ext/opencv/trackbar.cpp".freeze, "ext/opencv/trackbar.h".freeze, "ext/opencv/window.cpp".freeze, "ext/opencv/window.h".freeze, "images/CvMat_sobel.png".freeze, "images/CvMat_sub_rect.png".freeze, "images/CvSeq_relationmap.png".freeze, "lib/opencv.rb".freeze, "lib/opencv/psyched_yaml.rb".freeze, "lib/opencv/version.rb".freeze, "ruby-opencv.gemspec".freeze, "test/eigenfaces_save.xml".freeze, "test/fisherfaces_save.xml".freeze, "test/helper.rb".freeze, "test/lbph_save.xml".freeze, "test/runner.rb".freeze, "test/samples/airplane.jpg".freeze, "test/samples/baboon.jpg".freeze, "test/samples/baboon200.jpg".freeze, "test/samples/baboon200_rotated.jpg".freeze, "test/samples/blank0.jpg".freeze, "test/samples/blank1.jpg".freeze, "test/samples/blank2.jpg".freeze, "test/samples/blank3.jpg".freeze, "test/samples/blank4.jpg".freeze, "test/samples/blank5.jpg".freeze, "test/samples/blank6.jpg".freeze, "test/samples/blank7.jpg".freeze, "test/samples/blank8.jpg".freeze, "test/samples/blank9.jpg".freeze, "test/samples/cat.jpg".freeze, "test/samples/chessboard.jpg".freeze, "test/samples/contours.jpg".freeze, "test/samples/fruits.jpg".freeze, "test/samples/haarcascade_frontalface_alt.xml.gz".freeze, "test/samples/inpaint-mask.bmp".freeze, "test/samples/lena-256x256.jpg".freeze, "test/samples/lena-32x32.jpg".freeze, "test/samples/lena-eyes.jpg".freeze, "test/samples/lena-inpaint.jpg".freeze, "test/samples/lena.jpg".freeze, "test/samples/lines.jpg".freeze, "test/samples/messy0.jpg".freeze, "test/samples/messy1.jpg".freeze, "test/samples/movie_sample.avi".freeze, "test/samples/one_way_train_0000.jpg".freeze, "test/samples/one_way_train_0001.jpg".freeze, "test/samples/partially_blank0.jpg".freeze, "test/samples/partially_blank1.jpg".freeze, "test/samples/smooth0.jpg".freeze, "test/samples/smooth1.jpg".freeze, "test/samples/smooth2.jpg".freeze, "test/samples/smooth3.jpg".freeze, "test/samples/smooth4.jpg".freeze, "test/samples/smooth5.jpg".freeze, "test/samples/smooth6.jpg".freeze, "test/samples/str-cv-rotated.jpg".freeze, "test/samples/str-cv.jpg".freeze, "test/samples/str-ov.jpg".freeze, "test/samples/stuff.jpg".freeze, "test/test_curve.rb".freeze, "test/test_cvavgcomp.rb".freeze, "test/test_cvbox2d.rb".freeze, "test/test_cvcapture.rb".freeze, "test/test_cvchain.rb".freeze, "test/test_cvcircle32f.rb".freeze, "test/test_cvconnectedcomp.rb".freeze, "test/test_cvcontour.rb".freeze, "test/test_cvcontourtree.rb".freeze, "test/test_cverror.rb".freeze, "test/test_cvfeaturetree.rb".freeze, "test/test_cvfont.rb".freeze, "test/test_cvhaarclassifiercascade.rb".freeze, "test/test_cvhistogram.rb".freeze, "test/test_cvhumoments.rb".freeze, "test/test_cvline.rb".freeze, "test/test_cvmat.rb".freeze, "test/test_cvmat_drawing.rb".freeze, "test/test_cvmat_dxt.rb".freeze, "test/test_cvmat_imageprocessing.rb".freeze, "test/test_cvmoments.rb".freeze, "test/test_cvpoint.rb".freeze, "test/test_cvpoint2d32f.rb".freeze, "test/test_cvpoint3d32f.rb".freeze, "test/test_cvrect.rb".freeze, "test/test_cvscalar.rb".freeze, "test/test_cvseq.rb".freeze, "test/test_cvsize.rb".freeze, "test/test_cvsize2d32f.rb".freeze, "test/test_cvslice.rb".freeze, "test/test_cvsurfparams.rb".freeze, "test/test_cvsurfpoint.rb".freeze, "test/test_cvtermcriteria.rb".freeze, "test/test_cvtwopoints.rb".freeze, "test/test_cvvideowriter.rb".freeze, "test/test_eigenfaces.rb".freeze, "test/test_fisherfaces.rb".freeze, "test/test_iplconvkernel.rb".freeze, "test/test_iplimage.rb".freeze, "test/test_lbph.rb".freeze, "test/test_mouseevent.rb".freeze, "test/test_opencv.rb".freeze, "test/test_pointset.rb".freeze, "test/test_preliminary.rb".freeze, "test/test_trackbar.rb".freeze, "test/test_window.rb".freeze, "yard_extension.rb".freeze] + s.homepage = "https://github.com/ruby-opencv/ruby-opencv/".freeze + s.licenses = ["BSD-3-Clause".freeze] + s.rdoc_options = ["--main".freeze, "README.md".freeze] + s.rubygems_version = "2.6.10".freeze + s.summary = "OpenCV wrapper for Ruby".freeze + + if s.respond_to? :specification_version then + s.specification_version = 4 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_development_dependency(%q.freeze, ["~> 4.0"]) + s.add_development_dependency(%q.freeze, ["~> 0"]) + s.add_development_dependency(%q.freeze, ["~> 0"]) + s.add_development_dependency(%q.freeze, ["~> 3.15"]) + else + s.add_dependency(%q.freeze, ["~> 4.0"]) + s.add_dependency(%q.freeze, ["~> 0"]) + s.add_dependency(%q.freeze, ["~> 0"]) + s.add_dependency(%q.freeze, ["~> 3.15"]) + end + else + s.add_dependency(%q.freeze, ["~> 4.0"]) + s.add_dependency(%q.freeze, ["~> 0"]) + s.add_dependency(%q.freeze, ["~> 0"]) + s.add_dependency(%q.freeze, ["~> 3.15"]) + end +end diff --git a/setup/setup.cygwin.rb b/setup/setup.cygwin.rb deleted file mode 100755 index a5efcdd2..00000000 --- a/setup/setup.cygwin.rb +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/env ruby -# Create OpenCV cygwin library from Windows DLLs. -require 'pathname' -opencv_installed_dir = "C:/Program\ Files/OpenCV" -install_bindir = "/usr/local/bin" -install_libdir = "/usr/local/lib" -install_includedir = "/usr/local/include/opencv" - -STDOUT.sync = true -puts ">> Please tell me path installed OpenCV." -puts ">> note: default is #{opencv_installed_dir}" -print "opencv installed directory : " -input = gets.chomp! -opencv_installed_dir = input unless input.empty? -opencv_installed_dir = `cygpath -u "#{opencv_installed_dir}"`.chomp! - -puts "[step.1]" -puts ">> Checking directory..." -basedir = Pathname(opencv_installed_dir) -print ">> basedir #{basedir}" -raise "error: directory #{basedir} does not exist." unless File.directory?(basedir) -bindir = basedir + 'bin' -puts "...ok" -print ">> bindir #{bindir}" -raise "error: directory #{bindir} does not exist." unless File.directory?(bindir) -puts "...ok" -libdir = basedir + 'lib' -print ">> libdir #{libdir}" -raise "error: directory #{libdir} does not exist." unless File.directory?(libdir) -puts "...ok" - -puts "[step.2]" -puts ">> Searching OpenCV Windows DLLs..." -Dir.foreach(bindir){|filename| - next unless filename =~ /\d\d\d\.dll\Z/ - dllname = filename.scan(/(\D+)\d+\.dll/) - `echo EXPORTS > #{dllname}.def` - `nm "#{libdir + "#{dllname}.lib"}" | grep ' T _' | sed 's/.* T _//' >> #{dllname}.def` - `dlltool --def #{dllname}.def --dllname "#{filename}" --output-lib lib#{dllname}.dll.a` - `rm #{dllname}.def` - puts ">> Create lib#{dllname}.dll.a success." -} - -puts "[step.3]" -puts ">> Move libs to target directory" -puts ">> note: default is #{install_libdir}" -print "target directory : " -input = gets.chomp! -install_libdir = input unless input.empty? -if File.exist?(install_libdir) - raise "#{install_libdir} is exist. but it is not directory." unless File.directory?(install_libdir) -else - print "Directory #{install_libdir} does not exist. Create it? [y/n]:" - raise "Please create directory #{install_libdir}" unless gets.chomp! == 'y' - `mkdir -p #{install_libdir}` -end -`mv *.dll.a #{install_libdir}` - - -puts "[step.4]" -puts ">> Copy OpenCV header files(*.h / *.hpp) to target directory" -puts ">> note: default is #{install_includedir}" -print "target directory : " -input = gets.chomp! -install_includedir = input unless input.empty? -if File.exist?(install_includedir) - raise "#{install_includedir} is exist. but it is not directory." unless File.directory?(install_libdir) -else - print "Directory #{install_includedir} does not exist. Create it? [y/n]:" - raise "Please create directory #{install_includedir}" unless gets.chomp! == 'y' - `mkdir -p #{install_includedir}` -end -puts ">> Copying header files..." -[ - "cxcore/include", - "cv/include", - "cvaux/include", - "ml/include", - "otherlibs/cvcam/include", - "otherlibs/highgui" -].each{|i| - if File.directory?(basedir + i) - Dir.foreach(basedir + i){|filename| - next unless (File.extname(filename) == ".h" || File.extname(filename) == ".hpp") - `cp "#{basedir + i + filename}" #{install_includedir}` - } - end -} - - -puts "[step.5]" -puts ">> Copy OpenCV dll files (*.dll) to target directory" -puts ">> note: default is #{install_bindir}" -print "target directory : " -input = gets.chomp! -install_bindir = input unless input.empty? -if File.exist?(install_includedir) - raise "#{install_bindir} is exist. but it is not directory." unless File.directory?(install_libdir) -else - print "Directory #{install_bindir} does not exist. Create it? [y/n]:" - raise "Please create directory #{install_bindir}" unless gets.chomp! == 'y' - `mkdir -p #{install_bindir}` -end -puts ">> Copying dll files..." -Dir.foreach(bindir){|filename| - next if File.extname(filename) != ".dll" - `cp "#{bindir + filename}" #{install_bindir}` -} - -puts "Congratulation! Setup complete." -puts <> Please tell me path installed OpenCV." -puts ">> note: default is #{opencv_installed_dir}" -print "opencv installed directory : " -input = gets.chomp! -opencv_installed_dir = input unless input.empty? -#opencv_installed_dir = opencv_installed_dir.chomp! - -puts "[step.1]" -puts ">> Checking directory..." -basedir = Pathname(opencv_installed_dir) -print ">> basedir #{basedir}" -raise "error: directory #{basedir} does not exist." unless File.directory?(basedir) -bindir = basedir + 'bin' -puts "...ok" -print ">> bindir #{bindir}" -raise "error: directory #{bindir} does not exist." unless File.directory?(bindir) -puts "...ok" -libdir = basedir + 'lib' -print ">> libdir #{libdir}" -raise "error: directory #{libdir} does not exist." unless File.directory?(libdir) -puts "...ok" - -puts "[step.2]" -puts ">> Searching OpenCV Windows DLLs..." -Dir.foreach(bindir){|filename| - next unless filename =~ /\d\d\d\.dll\Z/ - dllname = filename.scan(/(\D+)\d+\.dll/) - `echo EXPORTS > #{dllname}.def` - `nm "#{libdir + "#{dllname}.lib"}" | grep ' T _' | sed 's/.* T _//' >> #{dllname}.def` - `dlltool --def #{dllname}.def --dllname "#{filename}" --output-lib #{dllname}.lib` - `rm #{dllname}.def` - puts ">> Create #{dllname}.lib success." -} - -puts "[step.3]" -puts ">> Move libs to target directory" -puts ">> note: default is #{install_libdir}" -print "target directory : " -input = gets.chomp! -install_libdir = input unless input.empty? -if File.exist?(install_libdir) - raise "#{install_libdir} is exist. but it is not directory." unless File.directory?(install_libdir) -else - print "Directory #{install_libdir} does not exist. Create it? [y/n]:" - raise "Please create directory #{install_libdir}" unless gets.chomp! == 'y' - `mkdir -p #{install_libdir}` -end -`mv *.lib #{install_libdir}` - - -puts "[step.4]" -puts ">> Copy OpenCV header files(*.h / *.hpp) to target directory" -puts ">> note: default is #{install_includedir}" -print "target directory : " -input = gets.chomp! -install_includedir = input unless input.empty? -if File.exist?(install_includedir) - raise "#{install_includedir} is exist. but it is not directory." unless File.directory?(install_libdir) -else - print "Directory #{install_includedir} does not exist. Create it? [y/n]:" - raise "Please create directory #{install_includedir}" unless gets.chomp! == 'y' - `mkdir -p #{install_includedir}` -end -puts ">> Copying header files..." -[ - "cxcore/include", - "cv/include", - "cvaux/include", - "ml/include", - "otherlibs/cvcam/include", - "otherlibs/highgui" -].each{|i| - if File.directory?(basedir + i) - Dir.foreach(basedir + i){|filename| - next unless (File.extname(filename) == ".h" || File.extname(filename) == ".hpp") - `cp "#{basedir + i + filename}" #{install_includedir}` - } - end -} - -puts "Congratulation! Setup complete." -puts <> Please tell me CPU archtecture." -archs = ["x86", "amd64", "ia64"] -archs.each_with_index{|v, i| - puts "[#{i}].#{v}" -} -print "CPU archtecture : " -input = gets.chomp!.to_i -arch = archs[input] -puts "you choose #{arch}" - -puts ">> Please tell me path installed OpenCV." -puts ">> note: default is #{opencv_installed_dir}" -print "opencv installed directory : " -input = gets.chomp! -opencv_installed_dir = input unless input.empty? - -puts "[step.1]" -puts ">> Checking directory..." -basedir = Pathname(opencv_installed_dir) -print ">> basedir #{basedir}" -raise "error: directory #{basedir} does not exist." unless File.directory?(basedir) -bindir = basedir + 'bin' -puts "...ok" -print ">> bindir #{bindir}" -raise "error: directory #{bindir} does not exist." unless File.directory?(bindir) -puts "...ok" -libdir = basedir + 'lib' -print ">> libdir #{libdir}" -raise "error: directory #{libdir} does not exist." unless File.directory?(libdir) -puts "...ok" - -puts "[step.2]" -puts ">> Searching OpenCV Windows DLLs..." -Dir.foreach(bindir){|filename| - next unless filename =~ /\d\d\d\.dll\Z/ - dllname = filename.scan(/(\D+)\d+\.dll/) - open("#{dllname}.def", "w"){|def_file| - def_file.puts "LIBRARY #{filename}" - def_file.puts "EXPORTS" - `dumpbin.exe /exports "#{bindir + filename}"`.split("\n").each{|line| - f = line.scan(/\A\s+\d+\s+[0-9A-F]+\s+[0-9A-F]+\s+(.*)/).first - def_file.puts f if f - } - } - `lib.exe /def:#{dllname}.def /machine:#{arch}` - File.unlink("#{dllname}.def") - puts ">> Create #{dllname}.lib success." -} - -puts "[step.3]" -puts ">> Move libs to target directory" -puts ">> note: default is #{install_libdir}" -print "target directory : " -input = gets.chomp! -install_libdir = input unless input.empty? -if File.exist?(install_libdir) - raise "#{install_libdir} is exist. but it is not directory." unless File.directory?(install_libdir) -else - print "Directory #{install_libdir} does not exist. Create it? [y/n]:" - raise "Please create directory #{install_libdir}" unless gets.chomp! == 'y' - `md #{install_libdir}` -end -puts "move" -`move *.lib #{install_libdir}` - -puts "[step.4]" -puts ">> Copy OpenCV header files(*.h / *.hpp) to target directory" -puts ">> note: default is #{install_includedir}" -print "target directory : " -input = gets.chomp! -install_includedir = input unless input.empty? -if File.exist?(install_includedir) - raise "#{install_includedir} is exist. but it is not directory." unless File.directory?(install_libdir) -else - print "Directory #{install_includedir} does not exist. Create it? [y/n]:" - raise "Please create directory #{install_includedir}" unless gets.chomp! == 'y' - `md #{install_includedir}` -end -puts ">> Copying header files..." -[ - "cxcore/include", - "cv/include", - "cvaux/include", - "ml/include", - "otherlibs/cvcam/include", - "otherlibs/highgui" -].each{|i| - if File.directory?(basedir + i) - Dir.foreach(basedir + i){|filename| - next unless (File.extname(filename) == ".h" || File.extname(filename) == ".hpp") - `copy \"#{(basedir + i + filename).to_s.gsub("/", "\\")}\" #{install_includedir}` - } - end -} diff --git a/test/eigenfaces_save.xml b/test/eigenfaces_save.xml new file mode 100644 index 00000000..ec3166e5 --- /dev/null +++ b/test/eigenfaces_save.xml @@ -0,0 +1,7524 @@ + + +1 + + 1 + 65536 +
d
+ + 162. 162. 162. 163. 164. 162. 158. 155. 158. 157. 156. 156. 155. + 155. 156. 156. 158. 159. 161. 164. 167. 169. 171. 172. 170. 170. + 167. 160. 152. 142. 127. 112. 98. 94. 95. 101. 105. 105. 105. 108. + 109. 109. 108. 107. 107. 108. 108. 109. 111. 107. 105. 108. 110. + 111. 115. 121. 118. 121. 124. 126. 126. 127. 128. 130. 133. 131. + 129. 130. 132. 133. 131. 129. 127. 129. 130. 129. 129. 130. 132. + 134. 133. 133. 133. 134. 134. 135. 135. 135. 134. 133. 132. 132. + 134. 134. 133. 132. 135. 136. 136. 136. 136. 135. 134. 133. 138. + 136. 133. 131. 130. 131. 132. 134. 131. 132. 133. 133. 131. 131. + 132. 133. 135. 135. 135. 134. 134. 134. 133. 133. 142. 136. 130. + 129. 132. 134. 132. 129. 129. 130. 132. 131. 129. 129. 130. 131. + 130. 130. 130. 129. 128. 127. 126. 125. 124. 124. 124. 121. 118. + 113. 108. 105. 109. 116. 127. 135. 141. 146. 151. 155. 161. 160. + 158. 154. 151. 150. 152. 154. 154. 155. 155. 156. 156. 155. 155. + 154. 152. 152. 152. 153. 153. 154. 154. 154. 156. 155. 155. 157. + 158. 158. 156. 153. 148. 170. 192. 203. 211. 220. 219. 212. 215. + 210. 180. 133. 104. 105. 110. 109. 116. 117. 119. 120. 121. 120. + 119. 119. 122. 123. 123. 122. 120. 120. 122. 124. 122. 123. 125. + 126. 125. 123. 121. 119. 126. 126. 126. 126. 126. 126. 126. 126. + 120. 121. 117. 121. 146. 172. 164. 138. 162. 161. 161. 162. 163. + 161. 158. 155. 157. 157. 156. 155. 154. 155. 155. 155. 156. 158. + 160. 163. 166. 169. 171. 172. 171. 171. 167. 159. 151. 141. 126. + 111. 97. 93. 94. 99. 103. 104. 104. 107. 107. 107. 107. 107. 107. + 107. 108. 108. 110. 106. 105. 108. 110. 111. 115. 120. 119. 122. + 124. 126. 126. 126. 127. 129. 133. 131. 129. 130. 132. 133. 131. + 129. 127. 129. 130. 130. 129. 130. 132. 134. 133. 133. 133. 134. + 134. 134. 135. 135. 134. 133. 131. 132. 134. 134. 133. 132. 134. + 135. 135. 135. 135. 134. 133. 132. 137. 135. 133. 131. 130. 130. + 131. 132. 131. 132. 133. 133. 131. 130. 132. 133. 134. 134. 134. + 134. 133. 133. 132. 132. 141. 135. 130. 129. 131. 133. 131. 128. + 128. 130. 131. 130. 129. 128. 129. 131. 129. 130. 130. 129. 128. + 127. 126. 125. 124. 124. 123. 121. 117. 112. 108. 105. 109. 116. + 127. 136. 142. 148. 153. 156. 161. 161. 159. 155. 151. 150. 151. + 153. 153. 154. 155. 155. 155. 155. 154. 153. 152. 152. 152. 153. + 153. 154. 154. 154. 156. 155. 155. 156. 158. 158. 155. 153. 151. + 171. 195. 208. 213. 216. 218. 217. 216. 207. 177. 135. 105. 100. + 105. 108. 116. 117. 119. 120. 121. 121. 120. 119. 122. 122. 123. + 122. 120. 120. 122. 124. 122. 123. 125. 125. 125. 123. 121. 120. + 126. 126. 126. 126. 126. 125. 125. 125. 113. 115. 115. 124. 153. + 179. 173. 150. 160. 159. 159. 160. 161. 160. 157. 154. 156. 156. + 155. 154. 154. 154. 154. 154. 154. 156. 159. 163. 166. 169. 171. + 172. 172. 171. 167. 158. 150. 140. 124. 110. 96. 92. 92. 97. 102. + 102. 103. 106. 105. 105. 105. 106. 106. 107. 107. 108. 109. 106. + 105. 108. 111. 111. 115. 120. 120. 122. 125. 126. 125. 125. 126. + 127. 132. 130. 129. 130. 131. 132. 131. 130. 128. 129. 130. 130. + 129. 129. 132. 134. 133. 133. 133. 133. 134. 134. 134. 135. 134. + 132. 131. 132. 133. 134. 133. 131. 133. 133. 134. 134. 133. 132. + 131. 131. 135. 134. 132. 130. 129. 129. 130. 131. 130. 132. 133. + 132. 131. 130. 131. 133. 133. 133. 133. 132. 132. 132. 131. 131. + 138. 134. 129. 128. 130. 132. 130. 128. 127. 128. 130. 129. 127. + 127. 128. 129. 129. 129. 129. 129. 128. 127. 126. 125. 123. 123. + 122. 119. 116. 111. 107. 105. 107. 114. 125. 135. 143. 149. 154. + 157. 160. 160. 159. 156. 153. 151. 151. 152. 152. 153. 154. 154. + 154. 154. 153. 152. 153. 153. 153. 153. 154. 154. 154. 154. 155. + 155. 154. 155. 157. 157. 155. 153. 151. 167. 191. 209. 213. 211. + 214. 220. 219. 207. 182. 146. 112. 96. 100. 110. 115. 116. 119. 120. + 121. 121. 121. 120. 121. 122. 123. 122. 120. 120. 122. 124. 122. + 123. 124. 125. 125. 123. 122. 120. 125. 125. 125. 125. 125. 125. + 125. 125. 117. 121. 123. 128. 144. 155. 140. 116. 159. 158. 157. + 158. 159. 158. 156. 154. 156. 155. 154. 153. 153. 153. 153. 154. + 153. 155. 159. 163. 167. 169. 171. 171. 172. 171. 166. 157. 148. + 138. 122. 108. 95. 91. 90. 95. 100. 100. 102. 105. 103. 103. 104. + 105. 106. 106. 106. 106. 108. 104. 105. 109. 111. 111. 115. 120. + 121. 123. 125. 126. 125. 124. 125. 126. 130. 129. 129. 130. 131. + 131. 131. 131. 128. 129. 130. 130. 129. 129. 131. 133. 132. 132. + 133. 133. 133. 134. 134. 134. 133. 132. 131. 131. 133. 134. 132. + 131. 132. 132. 132. 132. 132. 131. 130. 129. 133. 132. 131. 129. + 129. 128. 129. 129. 130. 131. 133. 132. 130. 130. 131. 132. 132. + 132. 132. 131. 131. 130. 130. 130. 135. 132. 129. 128. 130. 130. + 129. 127. 126. 127. 128. 128. 126. 126. 127. 128. 129. 129. 129. + 129. 129. 128. 127. 126. 123. 122. 121. 119. 115. 111. 108. 106. + 105. 111. 120. 131. 140. 147. 152. 155. 159. 160. 160. 158. 154. + 152. 152. 152. 152. 153. 153. 154. 154. 153. 153. 152. 153. 154. + 154. 154. 154. 154. 154. 154. 155. 154. 153. 154. 156. 156. 155. + 153. 151. 157. 176. 200. 210. 209. 211. 219. 219. 212. 197. 169. + 129. 99. 97. 111. 114. 115. 117. 120. 121. 121. 121. 121. 121. 122. + 122. 121. 120. 119. 121. 123. 122. 123. 124. 124. 124. 123. 122. + 122. 124. 124. 124. 125. 125. 125. 125. 125. 123. 128. 129. 123. + 115. 102. 80. 58. 158. 157. 156. 156. 158. 158. 156. 154. 156. 155. + 154. 153. 153. 153. 153. 154. 154. 156. 160. 164. 168. 170. 171. + 171. 172. 170. 164. 155. 146. 136. 121. 107. 95. 90. 89. 94. 98. 99. + 101. 105. 102. 103. 104. 106. 106. 106. 105. 105. 106. 103. 104. + 109. 111. 111. 114. 119. 120. 122. 125. 125. 124. 124. 124. 126. + 128. 129. 129. 130. 130. 130. 131. 132. 129. 130. 131. 130. 129. + 129. 131. 133. 132. 132. 132. 133. 133. 133. 134. 134. 133. 132. + 130. 131. 133. 133. 132. 131. 131. 131. 131. 131. 131. 130. 129. + 129. 132. 132. 131. 130. 129. 128. 128. 128. 130. 131. 132. 132. + 130. 129. 131. 132. 132. 132. 131. 131. 130. 130. 130. 130. 133. + 131. 130. 129. 129. 129. 129. 128. 125. 127. 128. 127. 126. 125. + 126. 128. 128. 128. 129. 129. 129. 128. 127. 126. 124. 123. 121. + 118. 115. 112. 109. 108. 103. 107. 114. 123. 134. 142. 148. 151. + 156. 158. 160. 159. 156. 154. 153. 153. 154. 154. 155. 155. 155. + 155. 154. 154. 155. 154. 154. 154. 154. 154. 154. 154. 155. 153. + 152. 152. 154. 155. 154. 153. 153. 150. 160. 185. 205. 211. 213. + 217. 216. 216. 213. 193. 150. 109. 98. 108. 111. 113. 116. 118. 120. + 121. 121. 121. 120. 121. 122. 121. 119. 119. 121. 123. 122. 123. + 123. 123. 124. 123. 123. 123. 124. 124. 124. 125. 125. 126. 126. + 126. 127. 127. 120. 103. 80. 61. 47. 40. 158. 156. 155. 156. 157. + 158. 156. 155. 156. 156. 155. 154. 154. 154. 154. 154. 155. 158. + 162. 166. 169. 170. 170. 170. 170. 169. 162. 153. 144. 135. 121. + 108. 95. 90. 89. 93. 97. 99. 101. 105. 103. 104. 106. 107. 107. 106. + 104. 103. 105. 102. 104. 109. 112. 112. 114. 119. 119. 121. 124. + 125. 124. 124. 125. 126. 126. 128. 130. 130. 129. 129. 131. 132. + 129. 130. 131. 130. 128. 128. 130. 132. 131. 132. 132. 132. 133. + 133. 133. 133. 133. 131. 130. 131. 132. 133. 132. 130. 131. 131. + 131. 131. 131. 130. 129. 128. 132. 132. 131. 130. 130. 129. 128. + 128. 129. 131. 132. 131. 130. 129. 130. 132. 132. 132. 132. 131. + 131. 130. 130. 130. 131. 131. 131. 130. 130. 129. 129. 129. 126. + 127. 128. 128. 126. 126. 127. 128. 127. 128. 128. 129. 129. 128. + 127. 127. 125. 124. 121. 119. 116. 113. 111. 110. 103. 104. 108. + 116. 127. 137. 145. 148. 153. 156. 159. 160. 158. 156. 155. 155. + 156. 156. 157. 158. 158. 157. 156. 156. 155. 155. 155. 155. 154. + 154. 154. 154. 155. 153. 151. 151. 153. 154. 153. 153. 157. 149. + 151. 170. 195. 211. 215. 215. 212. 217. 221. 208. 172. 130. 107. + 104. 108. 110. 113. 116. 119. 120. 120. 120. 120. 121. 121. 120. + 119. 119. 120. 122. 122. 122. 122. 123. 123. 123. 124. 124. 124. + 125. 125. 126. 126. 127. 128. 128. 133. 122. 102. 79. 56. 42. 43. + 50. 158. 157. 155. 155. 157. 158. 157. 156. 157. 157. 156. 155. 154. + 155. 155. 155. 158. 161. 165. 168. 170. 171. 170. 169. 168. 167. + 160. 151. 143. 135. 121. 109. 96. 91. 89. 93. 97. 99. 102. 106. 105. + 106. 108. 108. 107. 105. 103. 102. 103. 101. 103. 109. 112. 112. + 114. 118. 117. 120. 123. 124. 124. 124. 126. 127. 125. 128. 130. + 130. 128. 128. 131. 133. 130. 131. 131. 130. 128. 128. 130. 132. + 131. 131. 132. 132. 132. 133. 133. 133. 132. 131. 130. 130. 132. + 133. 131. 130. 131. 131. 132. 132. 131. 130. 129. 129. 132. 132. + 132. 132. 131. 130. 129. 128. 129. 130. 132. 131. 129. 129. 130. + 131. 133. 132. 132. 132. 131. 131. 131. 131. 130. 131. 132. 132. + 131. 130. 130. 130. 126. 128. 129. 128. 127. 126. 127. 129. 127. + 128. 128. 129. 129. 128. 128. 127. 126. 125. 122. 119. 116. 114. + 113. 112. 105. 104. 105. 111. 122. 134. 142. 146. 150. 154. 158. + 161. 160. 158. 157. 157. 159. 159. 160. 160. 160. 160. 159. 159. + 156. 156. 156. 155. 155. 154. 154. 154. 155. 153. 150. 150. 152. + 153. 153. 152. 157. 151. 148. 157. 180. 203. 213. 212. 215. 217. + 220. 215. 194. 160. 125. 103. 106. 108. 111. 114. 117. 118. 119. + 119. 120. 121. 121. 120. 119. 118. 120. 122. 122. 122. 122. 122. + 123. 123. 124. 125. 125. 125. 126. 127. 128. 129. 129. 130. 122. + 101. 77. 60. 48. 41. 45. 54. 159. 157. 155. 155. 157. 158. 158. 157. + 158. 157. 156. 156. 155. 155. 156. 156. 160. 162. 166. 170. 171. + 171. 169. 168. 167. 166. 159. 150. 143. 135. 122. 109. 97. 91. 89. + 93. 97. 99. 102. 107. 107. 108. 109. 109. 108. 105. 103. 101. 103. + 101. 103. 109. 112. 112. 114. 118. 116. 119. 122. 124. 124. 125. + 126. 128. 124. 127. 130. 130. 128. 128. 131. 133. 130. 131. 131. + 130. 128. 128. 130. 132. 131. 131. 131. 132. 132. 133. 133. 133. + 132. 131. 130. 130. 132. 132. 131. 130. 131. 132. 132. 132. 132. + 131. 130. 129. 132. 133. 133. 132. 131. 130. 129. 128. 129. 130. + 131. 131. 129. 129. 130. 131. 133. 133. 133. 132. 132. 132. 131. + 131. 130. 132. 133. 133. 131. 130. 130. 131. 127. 128. 129. 129. + 127. 127. 128. 129. 127. 127. 128. 129. 129. 129. 128. 128. 127. + 125. 123. 120. 117. 115. 114. 113. 108. 105. 103. 109. 120. 132. + 142. 146. 148. 152. 158. 161. 161. 159. 158. 158. 161. 161. 162. + 162. 162. 162. 161. 161. 156. 156. 156. 155. 155. 154. 154. 154. + 155. 152. 150. 150. 151. 153. 153. 152. 154. 152. 147. 147. 166. + 194. 208. 208. 221. 219. 218. 217. 210. 184. 141. 106. 104. 106. + 109. 113. 116. 117. 118. 118. 120. 121. 121. 120. 118. 118. 120. + 122. 122. 122. 122. 122. 123. 123. 125. 125. 126. 126. 127. 128. + 129. 130. 130. 131. 94. 71. 52. 49. 50. 48. 48. 51. 158. 158. 157. + 157. 157. 157. 157. 157. 155. 159. 161. 159. 154. 152. 156. 160. + 164. 165. 167. 169. 168. 167. 165. 163. 164. 163. 157. 149. 142. + 134. 120. 107. 96. 90. 87. 92. 97. 98. 99. 101. 107. 107. 107. 106. + 106. 106. 105. 105. 101. 102. 103. 106. 109. 112. 115. 116. 119. + 119. 120. 121. 123. 124. 125. 125. 129. 128. 127. 126. 127. 130. + 132. 134. 130. 131. 131. 132. 132. 131. 131. 130. 133. 132. 132. + 131. 131. 132. 132. 133. 136. 136. 135. 134. 133. 133. 133. 134. + 132. 133. 134. 133. 131. 130. 131. 132. 133. 132. 132. 132. 132. + 132. 132. 132. 130. 132. 133. 132. 129. 128. 131. 134. 132. 133. + 133. 134. 133. 132. 130. 129. 132. 132. 133. 132. 131. 130. 129. + 128. 129. 129. 129. 128. 128. 127. 127. 127. 131. 130. 130. 129. + 129. 128. 128. 128. 128. 125. 122. 120. 119. 117. 115. 113. 110. + 108. 106. 106. 111. 122. 136. 146. 146. 150. 155. 159. 160. 160. + 161. 163. 158. 159. 161. 162. 163. 163. 162. 161. 156. 157. 160. + 161. 160. 157. 154. 152. 155. 154. 153. 152. 152. 152. 153. 153. + 151. 151. 146. 144. 154. 176. 197. 207. 214. 217. 217. 217. 217. + 203. 167. 132. 104. 104. 106. 111. 115. 116. 116. 116. 121. 122. + 123. 124. 123. 122. 121. 120. 125. 124. 122. 122. 122. 124. 126. + 127. 127. 131. 132. 131. 133. 131. 117. 98. 56. 51. 45. 44. 45. 47. + 45. 42. 156. 156. 156. 157. 157. 157. 157. 157. 156. 159. 160. 157. + 153. 152. 157. 161. 164. 165. 167. 168. 168. 166. 164. 163. 162. + 161. 157. 150. 144. 137. 124. 111. 97. 91. 88. 93. 98. 99. 100. 103. + 107. 106. 106. 106. 105. 105. 105. 104. 101. 102. 103. 106. 109. + 112. 115. 116. 119. 119. 120. 121. 123. 124. 125. 125. 126. 127. + 128. 129. 130. 130. 131. 131. 130. 131. 131. 132. 132. 131. 131. + 130. 133. 132. 132. 131. 131. 132. 132. 133. 134. 133. 132. 132. + 131. 131. 131. 132. 130. 131. 133. 133. 131. 131. 132. 134. 132. + 132. 132. 132. 131. 131. 131. 131. 130. 131. 132. 131. 129. 128. + 131. 133. 132. 133. 135. 136. 135. 133. 131. 129. 132. 132. 132. + 132. 131. 130. 129. 128. 129. 129. 128. 128. 128. 127. 127. 127. + 130. 129. 129. 129. 128. 128. 127. 127. 127. 125. 122. 121. 120. + 118. 115. 112. 110. 108. 106. 106. 110. 121. 134. 144. 147. 151. + 156. 159. 160. 161. 162. 163. 158. 159. 161. 162. 162. 162. 161. + 161. 157. 158. 159. 159. 159. 157. 154. 153. 154. 154. 153. 152. + 152. 152. 152. 152. 149. 150. 150. 148. 150. 164. 187. 205. 212. + 216. 217. 218. 221. 212. 183. 153. 108. 104. 105. 111. 114. 112. + 113. 117. 120. 121. 123. 124. 125. 124. 123. 123. 123. 123. 124. + 125. 126. 127. 127. 127. 135. 130. 130. 136. 138. 122. 92. 67. 49. + 49. 48. 46. 46. 47. 50. 52. 154. 155. 155. 156. 156. 157. 157. 158. + 157. 158. 158. 155. 152. 153. 158. 163. 165. 166. 167. 167. 167. + 165. 163. 162. 160. 160. 157. 151. 146. 139. 127. 114. 98. 91. 88. + 93. 99. 100. 101. 104. 106. 105. 105. 105. 104. 104. 104. 103. 102. + 102. 104. 106. 109. 112. 114. 116. 119. 119. 120. 121. 123. 124. + 125. 125. 124. 126. 129. 131. 131. 131. 129. 128. 130. 130. 131. + 131. 131. 131. 130. 130. 132. 132. 131. 131. 131. 131. 132. 132. + 132. 131. 130. 129. 129. 129. 130. 130. 129. 130. 132. 132. 131. + 131. 133. 135. 130. 130. 130. 130. 130. 130. 131. 131. 129. 130. + 131. 130. 128. 128. 130. 132. 131. 133. 135. 137. 136. 134. 131. + 129. 132. 132. 132. 132. 131. 130. 128. 128. 129. 128. 128. 128. + 127. 127. 127. 127. 128. 128. 128. 127. 127. 127. 126. 126. 126. + 124. 123. 122. 121. 118. 114. 111. 111. 109. 106. 105. 109. 119. + 131. 140. 147. 151. 156. 159. 161. 162. 163. 164. 159. 160. 160. + 161. 162. 161. 161. 161. 159. 159. 158. 158. 157. 156. 155. 155. + 154. 153. 152. 151. 151. 151. 151. 152. 149. 149. 152. 152. 147. + 150. 172. 198. 207. 212. 215. 217. 221. 220. 202. 180. 125. 111. + 104. 110. 114. 110. 112. 121. 117. 118. 120. 122. 124. 124. 124. + 123. 120. 122. 125. 128. 130. 130. 129. 128. 133. 132. 135. 139. + 127. 97. 64. 44. 45. 49. 51. 49. 46. 47. 52. 57. 153. 153. 154. 155. + 156. 157. 158. 158. 158. 158. 157. 154. 152. 155. 160. 165. 166. + 166. 166. 166. 165. 163. 162. 161. 159. 160. 157. 151. 146. 139. + 125. 113. 96. 90. 87. 92. 98. 100. 101. 103. 105. 105. 104. 104. + 104. 103. 103. 103. 102. 103. 104. 106. 108. 111. 114. 115. 119. + 119. 120. 121. 123. 124. 125. 125. 125. 126. 128. 129. 130. 130. + 129. 128. 129. 130. 131. 131. 131. 131. 130. 129. 132. 132. 131. + 130. 130. 131. 132. 132. 130. 130. 129. 129. 128. 129. 129. 130. + 130. 132. 133. 132. 130. 130. 131. 132. 128. 128. 128. 129. 129. + 129. 129. 130. 129. 129. 129. 128. 128. 128. 129. 130. 129. 131. + 134. 136. 136. 133. 130. 128. 131. 132. 132. 131. 131. 129. 128. + 127. 128. 128. 128. 127. 127. 127. 126. 126. 126. 126. 126. 126. + 126. 126. 126. 126. 125. 124. 123. 123. 122. 119. 114. 110. 111. + 109. 106. 105. 108. 117. 128. 136. 146. 150. 155. 159. 161. 162. + 163. 164. 160. 160. 160. 160. 161. 161. 160. 160. 160. 159. 158. + 156. 155. 155. 156. 156. 154. 153. 152. 151. 151. 151. 151. 151. + 152. 148. 151. 154. 147. 141. 158. 184. 201. 209. 213. 214. 218. + 222. 213. 199. 154. 125. 104. 107. 113. 112. 115. 124. 116. 117. + 119. 121. 121. 121. 121. 120. 120. 121. 124. 127. 129. 130. 131. + 131. 127. 138. 142. 125. 95. 68. 52. 44. 48. 49. 50. 49. 47. 48. 51. + 54. 153. 154. 155. 156. 157. 158. 158. 159. 159. 158. 156. 154. 154. + 157. 162. 166. 167. 167. 166. 165. 163. 162. 160. 159. 160. 161. + 157. 151. 145. 136. 121. 108. 94. 88. 85. 90. 96. 98. 100. 102. 105. + 105. 104. 104. 104. 103. 103. 103. 103. 103. 104. 106. 108. 111. + 113. 115. 119. 119. 120. 121. 123. 124. 125. 125. 128. 128. 127. + 126. 126. 128. 129. 130. 129. 129. 130. 131. 131. 130. 129. 129. + 132. 131. 130. 130. 130. 130. 131. 132. 131. 130. 130. 129. 130. + 130. 131. 131. 134. 134. 134. 132. 129. 127. 127. 128. 126. 126. + 126. 127. 127. 128. 128. 129. 129. 128. 127. 126. 127. 128. 128. + 128. 127. 128. 131. 133. 133. 131. 129. 127. 131. 131. 131. 131. + 130. 129. 128. 127. 128. 128. 127. 127. 127. 126. 126. 126. 125. + 125. 125. 126. 126. 126. 126. 126. 125. 124. 123. 123. 122. 119. + 114. 110. 111. 109. 107. 106. 108. 116. 126. 134. 144. 149. 154. + 158. 160. 161. 163. 164. 160. 160. 160. 160. 159. 159. 160. 160. + 161. 160. 157. 155. 155. 155. 156. 157. 154. 153. 152. 151. 151. + 151. 152. 152. 156. 148. 147. 152. 148. 141. 149. 167. 195. 207. + 214. 214. 216. 221. 218. 210. 184. 144. 108. 101. 109. 112. 115. + 121. 119. 120. 121. 122. 122. 121. 120. 119. 121. 121. 122. 123. + 125. 128. 131. 133. 132. 140. 127. 90. 61. 54. 52. 47. 48. 46. 45. + 46. 50. 52. 51. 50. 155. 156. 156. 157. 157. 158. 159. 159. 160. + 158. 157. 156. 158. 161. 165. 167. 168. 167. 165. 164. 162. 160. + 159. 158. 161. 162. 158. 151. 144. 134. 118. 104. 92. 86. 84. 89. + 95. 97. 99. 102. 106. 105. 105. 105. 104. 104. 104. 103. 103. 104. + 105. 106. 108. 111. 113. 114. 119. 119. 120. 121. 123. 124. 125. + 125. 130. 128. 126. 125. 125. 126. 129. 130. 129. 129. 130. 130. + 130. 130. 129. 129. 131. 131. 130. 130. 130. 130. 131. 131. 131. + 131. 130. 130. 131. 131. 132. 133. 135. 136. 135. 132. 128. 126. + 125. 126. 124. 124. 125. 125. 126. 127. 127. 128. 128. 126. 125. + 125. 126. 127. 127. 126. 126. 127. 129. 130. 130. 130. 129. 128. + 131. 131. 131. 131. 130. 129. 127. 127. 127. 127. 127. 127. 126. + 126. 126. 125. 125. 125. 125. 126. 126. 126. 127. 127. 126. 124. + 123. 122. 121. 118. 114. 111. 111. 110. 108. 106. 109. 116. 126. + 134. 143. 147. 153. 157. 159. 160. 162. 163. 161. 160. 160. 159. + 158. 159. 159. 159. 161. 159. 158. 156. 155. 155. 156. 157. 155. + 154. 153. 153. 152. 152. 153. 153. 157. 149. 147. 150. 149. 144. + 146. 153. 185. 202. 215. 216. 216. 221. 222. 217. 204. 166. 123. + 102. 103. 110. 114. 115. 122. 123. 124. 125. 124. 123. 121. 120. + 122. 122. 121. 122. 124. 128. 131. 134. 138. 122. 89. 56. 47. 54. + 53. 41. 45. 42. 41. 45. 52. 56. 54. 52. 158. 158. 158. 158. 158. + 159. 159. 159. 160. 159. 158. 159. 162. 165. 167. 168. 168. 167. + 165. 163. 161. 159. 158. 157. 162. 163. 160. 153. 145. 135. 119. + 105. 93. 87. 84. 90. 96. 98. 100. 103. 107. 106. 106. 106. 105. 105. + 105. 104. 104. 104. 105. 106. 108. 111. 113. 114. 119. 119. 120. + 121. 123. 124. 125. 125. 128. 127. 127. 127. 127. 127. 127. 127. + 128. 129. 129. 130. 130. 129. 129. 128. 131. 130. 130. 129. 129. + 130. 130. 131. 130. 130. 130. 130. 130. 131. 132. 133. 134. 135. + 134. 132. 128. 126. 126. 126. 122. 123. 123. 124. 125. 126. 126. + 127. 128. 125. 123. 123. 126. 127. 126. 124. 128. 128. 128. 128. + 129. 130. 130. 131. 130. 131. 131. 130. 130. 128. 127. 126. 127. + 127. 127. 126. 126. 126. 125. 125. 125. 126. 126. 126. 127. 127. + 128. 128. 127. 125. 122. 121. 120. 118. 115. 112. 111. 110. 108. + 107. 110. 117. 127. 134. 141. 145. 151. 155. 157. 159. 161. 162. + 162. 161. 159. 158. 158. 158. 159. 159. 160. 159. 158. 157. 156. + 156. 156. 156. 156. 156. 155. 154. 153. 153. 154. 154. 153. 152. + 151. 149. 148. 146. 146. 146. 168. 190. 210. 215. 215. 220. 223. + 221. 216. 190. 148. 114. 103. 108. 113. 113. 119. 120. 122. 123. + 123. 122. 121. 120. 122. 123. 124. 125. 127. 129. 131. 132. 122. 87. + 53. 43. 49. 50. 46. 42. 44. 44. 46. 49. 52. 54. 54. 54. 160. 160. + 160. 159. 159. 159. 159. 159. 160. 159. 159. 161. 164. 167. 168. + 168. 169. 167. 165. 162. 160. 158. 157. 157. 162. 163. 160. 154. + 147. 137. 121. 107. 94. 87. 85. 91. 97. 100. 102. 104. 107. 107. + 107. 106. 106. 106. 105. 105. 104. 104. 105. 106. 108. 110. 112. + 114. 119. 119. 120. 121. 123. 124. 125. 125. 125. 126. 128. 129. + 129. 128. 126. 124. 128. 129. 129. 130. 130. 129. 129. 128. 131. + 130. 130. 129. 129. 130. 130. 131. 129. 129. 129. 129. 130. 131. + 132. 132. 132. 133. 133. 131. 129. 127. 127. 128. 121. 122. 122. + 123. 124. 125. 126. 126. 128. 125. 122. 123. 125. 127. 126. 124. + 130. 129. 128. 128. 129. 130. 132. 133. 130. 130. 130. 130. 129. + 128. 127. 126. 127. 127. 127. 126. 126. 125. 125. 125. 126. 126. + 126. 127. 127. 128. 128. 129. 128. 125. 122. 120. 119. 117. 115. + 113. 110. 110. 108. 108. 111. 118. 128. 135. 139. 144. 150. 154. + 156. 158. 160. 161. 162. 161. 159. 158. 157. 157. 158. 159. 159. + 159. 158. 158. 157. 156. 155. 155. 157. 156. 155. 155. 154. 154. + 155. 155. 149. 155. 156. 150. 146. 146. 146. 144. 152. 178. 203. + 211. 213. 218. 222. 221. 221. 207. 171. 127. 105. 109. 115. 115. + 113. 115. 117. 119. 120. 120. 120. 119. 122. 124. 127. 129. 131. + 131. 131. 130. 94. 57. 36. 47. 53. 41. 39. 52. 46. 50. 54. 53. 50. + 49. 51. 54. 158. 158. 158. 159. 159. 159. 160. 160. 160. 161. 162. + 164. 166. 168. 169. 170. 167. 166. 165. 161. 158. 156. 157. 158. + 162. 163. 160. 153. 146. 136. 120. 105. 95. 91. 90. 94. 98. 98. 100. + 103. 105. 106. 106. 106. 105. 103. 101. 100. 101. 101. 102. 104. + 106. 109. 112. 113. 120. 120. 121. 122. 123. 123. 124. 124. 126. + 127. 128. 129. 129. 129. 129. 128. 128. 127. 126. 126. 127. 129. + 131. 132. 134. 134. 134. 132. 131. 130. 131. 133. 130. 130. 130. + 130. 130. 130. 130. 130. 133. 133. 132. 131. 129. 127. 124. 123. + 122. 121. 119. 118. 118. 120. 122. 123. 126. 125. 125. 124. 123. + 122. 121. 120. 124. 126. 129. 131. 131. 130. 128. 126. 132. 131. + 130. 129. 128. 127. 127. 127. 127. 126. 125. 124. 125. 126. 127. + 128. 126. 126. 126. 126. 126. 126. 126. 126. 128. 127. 125. 122. + 120. 117. 115. 114. 114. 111. 108. 108. 111. 118. 126. 131. 139. + 142. 148. 152. 154. 156. 158. 160. 161. 160. 158. 157. 156. 157. + 158. 158. 155. 156. 156. 157. 157. 158. 158. 159. 155. 155. 154. + 154. 154. 155. 156. 156. 154. 153. 152. 152. 151. 149. 146. 143. + 141. 157. 183. 206. 213. 211. 215. 224. 222. 219. 212. 172. 120. + 109. 118. 111. 114. 116. 118. 119. 120. 120. 120. 119. 119. 124. + 127. 129. 133. 132. 120. 104. 57. 51. 44. 43. 47. 51. 51. 49. 51. + 51. 50. 50. 50. 51. 52. 53. 158. 158. 159. 159. 159. 160. 160. 161. + 160. 161. 162. 164. 166. 167. 168. 168. 166. 166. 164. 161. 157. + 156. 157. 159. 161. 162. 159. 153. 146. 135. 119. 104. 93. 89. 88. + 93. 97. 98. 100. 104. 104. 105. 105. 104. 104. 103. 102. 101. 102. + 102. 103. 105. 108. 110. 113. 114. 119. 120. 120. 121. 122. 123. + 123. 124. 125. 126. 127. 128. 128. 128. 128. 128. 127. 126. 126. + 126. 127. 128. 130. 131. 131. 131. 130. 129. 128. 128. 128. 129. + 130. 130. 130. 130. 130. 130. 130. 130. 132. 132. 131. 130. 128. + 126. 125. 124. 126. 124. 122. 120. 120. 123. 125. 127. 126. 126. + 125. 125. 126. 126. 127. 128. 126. 126. 128. 129. 130. 131. 131. + 131. 133. 132. 131. 129. 128. 127. 127. 127. 129. 128. 126. 125. + 124. 125. 125. 126. 126. 126. 126. 126. 126. 126. 126. 126. 127. + 126. 124. 122. 120. 118. 116. 115. 114. 111. 108. 108. 111. 118. + 126. 131. 138. 142. 147. 151. 153. 155. 158. 160. 160. 159. 158. + 157. 156. 157. 157. 158. 156. 156. 156. 157. 157. 157. 157. 157. + 156. 155. 155. 155. 155. 155. 156. 156. 154. 153. 152. 152. 151. + 150. 146. 143. 140. 151. 172. 196. 210. 213. 217. 222. 225. 220. + 214. 187. 139. 106. 102. 106. 110. 112. 115. 118. 121. 123. 124. + 124. 127. 127. 128. 130. 132. 120. 91. 63. 48. 44. 40. 41. 46. 51. + 51. 49. 52. 51. 51. 50. 50. 50. 51. 51. 160. 159. 159. 159. 159. + 160. 161. 162. 161. 162. 164. 166. 166. 166. 166. 165. 165. 165. + 163. 160. 157. 156. 158. 161. 160. 161. 158. 152. 145. 134. 118. + 104. 90. 86. 86. 92. 96. 98. 100. 104. 104. 103. 102. 102. 102. 102. + 102. 103. 103. 103. 104. 106. 109. 111. 114. 115. 118. 119. 119. + 120. 121. 122. 122. 123. 124. 125. 126. 127. 127. 127. 127. 126. + 125. 125. 125. 125. 126. 127. 129. 130. 130. 129. 128. 127. 127. + 127. 128. 128. 130. 130. 130. 130. 130. 129. 129. 129. 130. 129. + 129. 128. 127. 126. 126. 125. 126. 125. 122. 121. 121. 122. 124. + 126. 127. 126. 124. 121. 120. 120. 120. 120. 128. 127. 127. 128. + 129. 130. 131. 132. 134. 133. 131. 130. 128. 127. 127. 127. 131. + 129. 128. 126. 125. 124. 124. 124. 126. 126. 126. 126. 126. 126. + 126. 126. 125. 124. 123. 121. 120. 118. 117. 116. 114. 111. 108. + 107. 111. 117. 125. 130. 137. 141. 146. 150. 152. 154. 156. 158. + 159. 158. 157. 156. 156. 156. 157. 157. 157. 157. 157. 156. 156. + 156. 156. 156. 156. 156. 156. 156. 156. 155. 156. 156. 154. 153. + 151. 151. 151. 150. 147. 144. 140. 143. 156. 181. 204. 216. 219. + 219. 224. 222. 218. 207. 171. 117. 92. 104. 108. 109. 113. 117. 120. + 123. 125. 126. 124. 130. 134. 130. 117. 92. 60. 35. 45. 43. 42. 46. + 52. 57. 57. 55. 53. 52. 51. 50. 49. 49. 49. 49. 161. 160. 159. 159. + 159. 161. 162. 163. 164. 165. 166. 167. 167. 166. 164. 163. 163. + 163. 162. 159. 157. 157. 159. 162. 160. 160. 158. 151. 144. 134. + 117. 103. 88. 84. 84. 90. 96. 98. 101. 105. 103. 102. 101. 100. 100. + 101. 103. 104. 102. 103. 104. 106. 108. 111. 113. 115. 118. 118. + 119. 119. 120. 121. 122. 122. 123. 124. 125. 126. 126. 126. 126. + 125. 124. 124. 125. 125. 126. 127. 128. 128. 131. 130. 128. 128. + 129. 130. 129. 129. 130. 130. 130. 129. 129. 129. 129. 128. 128. + 128. 127. 127. 126. 126. 126. 127. 126. 126. 125. 124. 123. 122. + 122. 121. 125. 123. 121. 119. 118. 119. 120. 121. 125. 126. 126. + 127. 128. 128. 129. 129. 134. 133. 131. 129. 128. 127. 127. 127. + 129. 129. 128. 127. 126. 125. 125. 125. 126. 126. 126. 126. 126. + 126. 126. 126. 124. 123. 122. 121. 120. 118. 117. 117. 114. 111. + 108. 107. 110. 117. 124. 129. 136. 140. 145. 149. 150. 152. 154. + 156. 157. 157. 156. 156. 156. 156. 156. 156. 157. 157. 156. 156. + 155. 154. 154. 154. 156. 156. 156. 156. 156. 155. 155. 154. 154. + 152. 150. 150. 150. 149. 147. 145. 141. 137. 143. 166. 195. 215. + 220. 218. 219. 226. 222. 218. 201. 147. 103. 102. 108. 109. 112. + 114. 117. 119. 121. 122. 118. 131. 137. 120. 88. 59. 45. 42. 43. 44. + 46. 51. 57. 60. 59. 57. 54. 53. 51. 49. 48. 47. 47. 47. 162. 161. + 160. 159. 160. 161. 163. 164. 167. 168. 168. 167. 166. 164. 162. + 160. 160. 161. 161. 160. 158. 158. 160. 162. 160. 160. 158. 151. + 144. 134. 117. 103. 87. 83. 83. 90. 95. 98. 101. 105. 103. 102. 101. + 100. 100. 101. 103. 104. 101. 101. 102. 104. 107. 110. 112. 113. + 118. 118. 119. 119. 120. 121. 122. 122. 123. 123. 124. 125. 126. + 126. 125. 125. 123. 124. 125. 126. 127. 127. 127. 128. 131. 128. + 126. 127. 129. 130. 130. 128. 130. 130. 130. 129. 129. 128. 128. + 127. 128. 128. 126. 126. 126. 126. 127. 128. 125. 125. 126. 126. + 125. 123. 120. 118. 117. 117. 118. 118. 120. 123. 125. 127. 117. + 119. 122. 125. 128. 129. 129. 129. 132. 131. 130. 128. 127. 127. + 127. 127. 127. 127. 127. 128. 128. 127. 127. 127. 126. 126. 126. + 126. 126. 126. 126. 126. 123. 123. 122. 120. 119. 118. 117. 116. + 114. 112. 108. 107. 110. 116. 123. 128. 135. 139. 144. 147. 149. + 150. 152. 154. 155. 155. 156. 156. 156. 156. 156. 156. 156. 156. + 156. 155. 154. 154. 153. 153. 155. 155. 156. 156. 156. 154. 153. + 152. 153. 151. 149. 148. 148. 148. 147. 145. 143. 137. 138. 154. + 183. 208. 218. 217. 215. 230. 224. 217. 215. 180. 126. 100. 106. + 107. 108. 111. 114. 117. 119. 120. 131. 131. 120. 94. 61. 40. 41. + 51. 41. 43. 47. 51. 55. 56. 54. 52. 53. 52. 50. 49. 47. 46. 46. 45. + 164. 162. 161. 159. 160. 162. 164. 166. 170. 169. 167. 164. 162. + 160. 158. 157. 156. 158. 160. 161. 160. 159. 160. 161. 160. 161. + 158. 152. 145. 134. 118. 104. 87. 84. 84. 90. 96. 98. 101. 105. 104. + 103. 102. 102. 102. 102. 102. 103. 100. 101. 102. 104. 106. 109. + 111. 113. 118. 119. 119. 120. 121. 122. 122. 123. 123. 124. 125. + 126. 126. 126. 125. 125. 124. 124. 126. 127. 128. 128. 128. 128. + 129. 126. 123. 124. 128. 130. 128. 126. 130. 130. 129. 129. 128. + 127. 127. 127. 130. 129. 127. 126. 126. 126. 128. 129. 120. 121. + 121. 122. 122. 122. 122. 121. 120. 120. 119. 118. 117. 116. 114. + 114. 115. 116. 119. 122. 125. 128. 129. 130. 128. 128. 127. 126. + 126. 127. 128. 128. 126. 126. 127. 128. 129. 129. 128. 128. 126. + 126. 126. 126. 126. 126. 126. 126. 124. 123. 122. 120. 119. 117. + 116. 115. 114. 112. 108. 107. 109. 115. 123. 127. 134. 138. 142. + 146. 147. 148. 150. 152. 153. 154. 155. 156. 156. 156. 155. 155. + 154. 154. 154. 154. 154. 153. 153. 153. 153. 154. 155. 155. 155. + 153. 151. 150. 151. 149. 146. 145. 146. 146. 145. 144. 143. 140. + 138. 146. 167. 194. 211. 216. 215. 230. 226. 214. 216. 202. 153. + 107. 102. 103. 105. 109. 113. 117. 121. 123. 143. 119. 88. 63. 48. + 40. 41. 44. 46. 48. 52. 55. 56. 56. 54. 52. 52. 51. 49. 48. 46. 45. + 45. 45. 165. 163. 161. 160. 160. 162. 165. 167. 170. 167. 163. 159. + 156. 154. 154. 154. 152. 156. 160. 163. 162. 161. 160. 160. 161. + 162. 159. 153. 146. 135. 119. 104. 89. 85. 85. 91. 96. 98. 101. 104. + 104. 105. 105. 104. 104. 103. 102. 101. 101. 102. 103. 105. 107. + 110. 112. 114. 119. 120. 120. 121. 122. 123. 123. 124. 124. 124. + 125. 126. 127. 127. 126. 126. 124. 125. 127. 128. 129. 129. 129. + 128. 130. 126. 123. 124. 129. 131. 130. 127. 130. 130. 129. 129. + 128. 127. 126. 126. 132. 131. 128. 127. 126. 127. 128. 129. 128. + 127. 125. 125. 128. 133. 139. 143. 144. 144. 143. 140. 136. 131. + 127. 124. 127. 125. 122. 120. 119. 121. 124. 126. 124. 124. 124. + 125. 125. 127. 128. 129. 127. 128. 129. 129. 129. 128. 127. 126. + 126. 126. 126. 126. 126. 126. 126. 126. 125. 124. 122. 120. 118. + 116. 114. 113. 115. 112. 108. 106. 109. 115. 122. 127. 134. 137. + 142. 144. 146. 147. 149. 150. 152. 153. 154. 155. 156. 155. 155. + 154. 153. 153. 153. 153. 153. 154. 154. 154. 152. 153. 154. 154. + 153. 151. 149. 147. 149. 147. 144. 143. 144. 145. 144. 143. 142. + 144. 142. 140. 152. 177. 201. 214. 218. 224. 226. 219. 216. 214. + 183. 134. 104. 105. 107. 109. 113. 118. 121. 124. 121. 91. 60. 46. + 45. 44. 42. 42. 50. 53. 56. 58. 59. 58. 56. 56. 51. 50. 48. 47. 46. + 45. 45. 45. 165. 164. 161. 160. 160. 162. 165. 167. 169. 166. 160. + 155. 151. 150. 150. 151. 150. 154. 161. 164. 164. 161. 159. 159. + 162. 163. 160. 153. 146. 136. 120. 105. 90. 86. 86. 92. 96. 98. 100. + 104. 105. 106. 106. 106. 105. 103. 101. 100. 103. 103. 104. 106. + 108. 111. 114. 115. 120. 120. 121. 122. 123. 123. 124. 124. 124. + 125. 126. 127. 127. 127. 127. 126. 124. 126. 128. 129. 130. 130. + 129. 129. 133. 129. 125. 127. 132. 134. 133. 129. 130. 130. 129. + 128. 127. 127. 126. 125. 134. 132. 129. 127. 126. 127. 128. 129. + 146. 143. 138. 137. 143. 153. 165. 172. 171. 173. 175. 177. 177. + 174. 171. 169. 144. 137. 128. 119. 114. 114. 117. 120. 122. 122. + 123. 123. 125. 126. 128. 129. 129. 130. 130. 130. 129. 127. 125. + 124. 126. 126. 126. 126. 126. 126. 126. 126. 126. 125. 123. 120. + 118. 115. 113. 112. 115. 112. 108. 106. 109. 115. 122. 126. 133. + 137. 141. 144. 145. 146. 148. 149. 151. 152. 154. 155. 156. 155. + 154. 154. 151. 152. 152. 153. 153. 154. 154. 155. 151. 152. 153. + 154. 153. 150. 148. 146. 148. 146. 143. 142. 143. 144. 143. 142. + 140. 146. 145. 138. 142. 165. 195. 212. 220. 218. 227. 226. 218. + 222. 205. 163. 110. 110. 110. 111. 114. 116. 119. 121. 82. 65. 48. + 43. 44. 43. 46. 50. 47. 50. 53. 55. 55. 54. 54. 54. 50. 49. 48. 46. + 46. 45. 46. 46. 166. 162. 158. 157. 160. 164. 168. 170. 168. 163. + 156. 151. 149. 148. 147. 146. 150. 156. 162. 164. 162. 159. 159. + 160. 165. 164. 159. 152. 146. 138. 122. 107. 93. 86. 83. 88. 94. 95. + 97. 99. 106. 105. 105. 104. 104. 103. 103. 103. 102. 103. 106. 109. + 111. 113. 114. 114. 117. 120. 122. 122. 120. 120. 122. 125. 127. + 127. 126. 126. 126. 127. 128. 129. 122. 129. 132. 130. 130. 133. + 131. 125. 128. 125. 127. 133. 132. 125. 121. 124. 134. 131. 128. + 128. 129. 128. 124. 119. 122. 131. 137. 138. 140. 146. 147. 143. + 144. 143. 149. 159. 163. 163. 167. 174. 176. 173. 173. 176. 183. + 187. 188. 187. 184. 185. 177. 159. 141. 130. 122. 117. 115. 118. + 122. 124. 122. 121. 124. 129. 127. 133. 135. 130. 128. 131. 132. + 128. 130. 129. 129. 128. 128. 127. 127. 127. 126. 124. 121. 119. + 119. 117. 115. 112. 115. 110. 108. 109. 109. 112. 120. 129. 134. + 138. 143. 145. 145. 144. 143. 143. 148. 150. 152. 154. 155. 156. + 155. 155. 150. 153. 155. 155. 152. 151. 153. 156. 155. 154. 152. + 150. 149. 148. 148. 148. 145. 144. 143. 143. 142. 142. 143. 143. + 142. 140. 142. 144. 142. 148. 175. 206. 210. 218. 221. 220. 223. + 226. 213. 195. 140. 112. 104. 111. 115. 127. 120. 89. 49. 46. 43. + 42. 44. 47. 49. 49. 53. 54. 55. 57. 57. 58. 58. 58. 46. 44. 45. 49. + 50. 47. 47. 50. 164. 161. 158. 158. 161. 165. 169. 170. 165. 162. + 155. 149. 144. 143. 143. 144. 149. 155. 162. 164. 162. 160. 160. + 161. 165. 164. 159. 152. 147. 138. 122. 106. 93. 87. 85. 90. 96. 98. + 99. 102. 105. 105. 104. 104. 103. 103. 103. 102. 103. 104. 106. 108. + 111. 113. 115. 116. 118. 120. 122. 122. 121. 121. 123. 125. 127. + 126. 126. 126. 126. 127. 128. 129. 127. 130. 130. 126. 128. 132. + 131. 127. 139. 130. 123. 122. 122. 122. 129. 137. 130. 130. 130. + 128. 128. 128. 129. 131. 136. 144. 149. 147. 146. 149. 149. 147. + 148. 150. 158. 167. 169. 166. 169. 175. 180. 178. 177. 177. 177. + 177. 176. 174. 175. 184. 190. 190. 185. 174. 156. 142. 124. 117. + 112. 115. 122. 124. 121. 117. 128. 132. 133. 131. 130. 131. 126. + 118. 128. 127. 127. 127. 126. 126. 125. 125. 125. 122. 120. 119. + 118. 117. 115. 113. 115. 111. 108. 109. 110. 112. 120. 130. 135. + 138. 143. 146. 145. 144. 143. 143. 148. 149. 151. 153. 155. 155. + 155. 154. 151. 153. 154. 153. 152. 152. 153. 154. 153. 152. 151. + 149. 148. 147. 147. 146. 144. 144. 143. 142. 141. 141. 142. 142. + 143. 140. 141. 143. 140. 143. 164. 188. 208. 215. 218. 218. 224. + 229. 219. 204. 170. 126. 108. 120. 122. 112. 88. 55. 45. 43. 41. 41. + 43. 46. 47. 47. 53. 54. 54. 54. 55. 54. 54. 54. 45. 42. 43. 46. 46. + 43. 42. 45. 161. 159. 158. 159. 163. 167. 169. 170. 162. 159. 154. + 145. 137. 135. 138. 142. 149. 155. 162. 165. 163. 161. 162. 163. + 165. 164. 159. 153. 147. 138. 121. 105. 91. 85. 83. 89. 95. 98. 100. + 102. 104. 103. 103. 103. 103. 102. 102. 102. 105. 105. 106. 107. + 110. 113. 116. 118. 119. 121. 122. 122. 122. 122. 124. 125. 126. + 126. 125. 125. 126. 126. 127. 128. 132. 131. 127. 124. 126. 131. + 131. 127. 133. 129. 127. 128. 128. 126. 128. 132. 125. 127. 128. + 125. 123. 126. 134. 141. 142. 150. 154. 150. 144. 143. 144. 144. + 149. 155. 164. 172. 171. 167. 168. 173. 180. 181. 181. 179. 175. + 171. 168. 167. 180. 183. 184. 187. 192. 195. 189. 180. 167. 151. + 129. 115. 112. 117. 123. 126. 120. 122. 122. 123. 127. 131. 128. + 122. 125. 125. 125. 125. 124. 124. 124. 124. 122. 120. 118. 118. + 118. 117. 115. 113. 115. 111. 108. 109. 110. 113. 121. 130. 135. + 139. 143. 146. 146. 144. 143. 143. 148. 149. 150. 152. 153. 154. + 154. 154. 153. 152. 151. 151. 152. 153. 152. 150. 150. 150. 149. + 148. 147. 146. 145. 144. 143. 142. 141. 141. 140. 140. 141. 141. + 144. 140. 139. 141. 138. 137. 148. 164. 199. 209. 216. 218. 224. + 230. 226. 217. 208. 153. 122. 126. 119. 92. 61. 38. 42. 42. 41. 43. + 46. 49. 49. 48. 54. 53. 53. 52. 51. 50. 49. 49. 50. 47. 47. 49. 48. + 44. 43. 46. 158. 158. 159. 162. 166. 169. 169. 168. 158. 156. 150. + 139. 130. 128. 135. 142. 148. 155. 162. 165. 164. 163. 163. 165. + 165. 164. 160. 153. 147. 138. 120. 104. 87. 81. 79. 85. 92. 95. 97. + 100. 102. 102. 102. 102. 102. 101. 101. 101. 107. 106. 106. 107. + 109. 113. 117. 119. 120. 121. 122. 122. 122. 123. 124. 125. 125. + 125. 124. 124. 125. 126. 127. 127. 133. 130. 125. 124. 128. 131. + 129. 126. 124. 124. 126. 128. 128. 126. 125. 125. 131. 130. 127. + 125. 125. 131. 141. 148. 141. 147. 151. 147. 142. 139. 142. 145. + 145. 153. 162. 166. 164. 162. 166. 171. 173. 177. 181. 180. 176. + 173. 172. 173. 184. 181. 175. 172. 178. 189. 197. 198. 197. 192. + 175. 147. 123. 114. 117. 123. 118. 119. 120. 121. 124. 129. 131. + 132. 124. 124. 124. 124. 124. 124. 124. 124. 120. 119. 117. 116. + 117. 117. 115. 113. 114. 110. 108. 109. 110. 113. 121. 131. 135. + 139. 144. 146. 146. 145. 144. 144. 147. 148. 149. 150. 152. 153. + 153. 153. 154. 151. 149. 149. 152. 152. 150. 147. 147. 147. 147. + 146. 145. 144. 143. 143. 142. 141. 140. 139. 139. 139. 140. 140. + 143. 139. 138. 140. 139. 136. 138. 144. 183. 200. 217. 222. 223. + 226. 228. 227. 223. 183. 144. 120. 94. 67. 50. 43. 43. 43. 45. 48. + 52. 54. 53. 51. 55. 54. 53. 51. 49. 48. 47. 47. 54. 50. 49. 50. 49. + 45. 44. 47. 158. 159. 162. 165. 169. 169. 167. 165. 155. 151. 143. + 130. 122. 124. 134. 144. 149. 155. 163. 166. 165. 164. 164. 165. + 165. 164. 160. 154. 148. 138. 120. 103. 86. 80. 78. 84. 91. 94. 96. + 99. 100. 100. 100. 100. 100. 101. 101. 101. 106. 106. 105. 106. 109. + 112. 116. 119. 120. 120. 120. 121. 123. 124. 124. 124. 124. 124. + 124. 124. 124. 125. 126. 126. 130. 127. 125. 127. 130. 130. 127. + 126. 127. 125. 121. 118. 121. 128. 136. 140. 141. 135. 129. 127. + 131. 139. 145. 149. 141. 144. 147. 148. 145. 144. 149. 154. 144. + 150. 155. 157. 156. 159. 165. 170. 166. 171. 176. 178. 176. 175. + 176. 178. 174. 181. 186. 185. 185. 189. 191. 190. 190. 201. 205. + 190. 164. 138. 116. 102. 119. 122. 127. 129. 127. 125. 126. 129. + 124. 124. 124. 124. 124. 124. 124. 124. 119. 117. 115. 115. 116. + 115. 113. 112. 113. 109. 107. 108. 109. 112. 121. 131. 136. 139. + 144. 147. 146. 145. 144. 144. 147. 147. 147. 148. 150. 151. 152. + 153. 154. 151. 148. 148. 150. 151. 148. 144. 145. 145. 146. 146. + 145. 144. 142. 141. 142. 141. 140. 139. 139. 139. 139. 139. 142. + 139. 139. 141. 141. 138. 136. 137. 164. 189. 215. 224. 221. 220. + 225. 231. 218. 212. 173. 111. 63. 43. 41. 45. 43. 44. 46. 50. 54. + 55. 54. 53. 56. 55. 53. 51. 49. 48. 48. 48. 51. 47. 45. 46. 45. 42. + 42. 45. 160. 161. 165. 169. 171. 169. 164. 159. 152. 144. 131. 119. + 114. 120. 134. 145. 151. 157. 164. 167. 166. 164. 164. 165. 165. + 165. 161. 155. 148. 138. 119. 102. 88. 82. 80. 85. 92. 94. 96. 99. + 98. 99. 99. 99. 99. 100. 100. 100. 104. 104. 105. 106. 109. 112. + 115. 117. 120. 119. 118. 120. 122. 123. 123. 122. 124. 123. 123. + 123. 123. 124. 125. 126. 127. 125. 126. 129. 130. 127. 127. 129. + 126. 130. 134. 136. 141. 147. 149. 148. 137. 131. 123. 123. 128. + 135. 139. 139. 138. 137. 138. 142. 144. 145. 150. 156. 146. 150. + 153. 152. 155. 161. 167. 168. 164. 167. 171. 173. 173. 174. 175. + 176. 174. 184. 191. 190. 188. 189. 190. 190. 191. 197. 200. 198. + 194. 180. 150. 121. 109. 112. 119. 126. 125. 121. 120. 122. 123. + 123. 123. 123. 124. 124. 124. 124. 119. 117. 115. 114. 114. 114. + 112. 110. 111. 107. 105. 106. 108. 111. 120. 130. 136. 140. 145. + 147. 147. 145. 145. 145. 146. 146. 146. 147. 148. 150. 151. 152. + 153. 151. 149. 148. 148. 147. 145. 144. 143. 144. 145. 146. 145. + 144. 142. 141. 142. 141. 140. 139. 139. 139. 139. 140. 141. 140. + 140. 142. 143. 141. 139. 137. 148. 174. 204. 219. 219. 217. 223. + 231. 219. 235. 193. 104. 48. 36. 38. 41. 43. 43. 45. 48. 52. 54. 53. + 52. 56. 54. 52. 50. 49. 50. 50. 51. 51. 47. 45. 47. 47. 45. 46. 50. + 162. 164. 168. 172. 172. 168. 160. 154. 147. 136. 119. 107. 106. + 117. 134. 146. 153. 159. 165. 168. 166. 164. 163. 165. 165. 165. + 161. 155. 149. 138. 118. 101. 88. 82. 79. 85. 90. 92. 94. 97. 97. + 97. 98. 98. 99. 99. 99. 100. 102. 102. 104. 106. 109. 111. 113. 114. + 119. 117. 116. 118. 121. 123. 122. 120. 123. 123. 122. 122. 123. + 124. 124. 125. 125. 124. 126. 129. 126. 123. 128. 136. 121. 133. + 146. 151. 154. 152. 144. 133. 126. 124. 121. 120. 123. 127. 131. + 133. 135. 129. 127. 133. 138. 140. 142. 147. 149. 152. 152. 152. + 157. 164. 165. 161. 168. 167. 168. 170. 173. 176. 176. 175. 184. + 186. 185. 180. 181. 187. 191. 192. 197. 196. 190. 188. 197. 203. + 190. 170. 130. 119. 111. 114. 118. 118. 119. 122. 120. 121. 121. + 121. 122. 122. 123. 123. 119. 117. 115. 114. 113. 112. 110. 107. + 109. 105. 103. 105. 107. 110. 119. 128. 136. 140. 145. 147. 147. + 146. 145. 145. 146. 145. 145. 145. 147. 149. 151. 152. 151. 151. + 151. 149. 146. 144. 143. 144. 143. 144. 145. 146. 146. 144. 142. + 141. 142. 142. 141. 140. 140. 140. 140. 140. 141. 142. 143. 142. + 143. 143. 141. 140. 140. 158. 185. 207. 217. 220. 224. 228. 227. + 236. 177. 83. 40. 40. 42. 41. 45. 45. 46. 48. 52. 54. 54. 52. 53. + 52. 50. 49. 49. 50. 52. 53. 51. 47. 46. 49. 50. 49. 52. 56. 164. + 166. 170. 173. 173. 167. 157. 150. 144. 130. 111. 99. 101. 115. 133. + 145. 154. 160. 166. 168. 166. 163. 163. 164. 165. 165. 162. 156. + 149. 138. 118. 101. 86. 80. 77. 82. 88. 89. 91. 93. 96. 97. 97. 98. + 98. 99. 99. 99. 100. 101. 104. 106. 109. 111. 112. 112. 119. 117. + 115. 117. 121. 122. 121. 119. 123. 122. 122. 122. 122. 123. 124. + 125. 125. 124. 126. 127. 123. 120. 129. 142. 127. 134. 137. 135. + 133. 133. 128. 119. 123. 125. 127. 126. 125. 126. 132. 137. 138. + 128. 124. 130. 137. 137. 139. 142. 150. 152. 152. 153. 159. 165. + 162. 153. 171. 169. 167. 170. 176. 180. 180. 179. 185. 185. 184. + 183. 186. 191. 188. 181. 184. 192. 195. 191. 195. 204. 202. 193. + 181. 151. 120. 109. 112. 115. 119. 122. 118. 119. 119. 120. 120. + 121. 121. 121. 120. 117. 115. 113. 113. 111. 108. 106. 108. 104. + 102. 104. 106. 109. 118. 128. 136. 140. 145. 147. 147. 146. 145. + 145. 145. 145. 144. 145. 146. 148. 150. 152. 150. 152. 152. 149. + 144. 141. 142. 144. 142. 144. 145. 147. 146. 145. 142. 141. 143. + 142. 141. 140. 140. 140. 141. 141. 141. 143. 144. 143. 142. 142. + 142. 141. 137. 148. 170. 196. 215. 224. 226. 227. 229. 218. 142. 52. + 29. 41. 45. 44. 50. 49. 49. 51. 54. 56. 56. 55. 50. 49. 48. 47. 48. + 50. 53. 55. 46. 42. 42. 45. 47. 47. 50. 55. 168. 173. 176. 173. 169. + 164. 155. 145. 131. 121. 101. 85. 92. 117. 136. 141. 155. 162. 167. + 166. 165. 166. 164. 160. 165. 165. 162. 156. 150. 139. 121. 104. 85. + 78. 75. 79. 86. 89. 93. 96. 93. 93. 95. 96. 98. 99. 100. 101. 103. + 103. 103. 105. 106. 108. 110. 111. 119. 116. 114. 116. 119. 121. + 121. 119. 124. 124. 123. 122. 122. 122. 123. 123. 123. 132. 118. + 126. 115. 134. 142. 169. 110. 118. 127. 129. 126. 121. 120. 121. + 123. 123. 122. 122. 124. 127. 132. 135. 127. 128. 129. 132. 135. + 138. 141. 142. 149. 146. 145. 149. 155. 158. 156. 152. 164. 165. + 166. 168. 171. 177. 184. 189. 184. 188. 187. 183. 184. 190. 192. + 189. 188. 189. 192. 194. 195. 195. 195. 195. 198. 189. 160. 122. + 107. 114. 114. 104. 111. 117. 129. 127. 114. 114. 121. 117. 119. + 118. 117. 115. 113. 112. 110. 110. 109. 104. 101. 102. 105. 109. + 120. 131. 136. 140. 146. 149. 149. 147. 146. 146. 144. 144. 145. + 146. 146. 146. 145. 145. 149. 152. 154. 152. 147. 142. 141. 141. + 140. 140. 141. 143. 146. 146. 145. 143. 144. 144. 143. 141. 141. + 141. 141. 141. 141. 142. 143. 144. 145. 144. 143. 142. 143. 141. + 154. 185. 210. 220. 223. 227. 231. 166. 82. 32. 33. 51. 50. 36. 45. + 50. 54. 55. 54. 53. 56. 58. 53. 46. 39. 40. 47. 52. 51. 47. 42. 43. + 43. 44. 50. 55. 50. 41. 167. 172. 173. 169. 165. 160. 150. 140. 126. + 112. 91. 81. 91. 115. 134. 143. 154. 162. 167. 166. 165. 166. 164. + 161. 165. 165. 160. 154. 148. 138. 120. 104. 83. 77. 74. 80. 86. 89. + 92. 95. 95. 95. 96. 97. 98. 99. 100. 101. 102. 102. 103. 104. 105. + 107. 109. 110. 118. 116. 114. 115. 118. 120. 120. 119. 123. 123. + 122. 122. 122. 123. 124. 124. 127. 121. 134. 116. 122. 126. 153. + 143. 99. 107. 117. 122. 121. 119. 118. 119. 124. 122. 121. 122. 125. + 130. 133. 135. 125. 127. 130. 134. 136. 137. 137. 136. 142. 141. + 141. 145. 151. 156. 156. 155. 170. 172. 174. 176. 178. 180. 185. + 188. 181. 185. 186. 183. 184. 189. 191. 188. 188. 190. 192. 194. + 196. 196. 196. 196. 193. 195. 194. 178. 143. 110. 102. 111. 118. + 107. 105. 107. 109. 118. 122. 112. 117. 116. 115. 114. 112. 110. + 109. 108. 109. 104. 101. 102. 104. 109. 119. 130. 138. 143. 148. + 152. 152. 150. 149. 149. 144. 145. 145. 145. 145. 144. 144. 144. + 144. 147. 151. 151. 148. 144. 142. 142. 140. 140. 141. 144. 146. + 146. 145. 143. 144. 143. 142. 141. 141. 141. 142. 142. 141. 142. + 143. 144. 145. 144. 143. 143. 146. 143. 142. 158. 192. 223. 227. + 215. 173. 104. 48. 42. 47. 37. 35. 46. 45. 48. 52. 54. 54. 54. 55. + 55. 49. 46. 45. 46. 50. 51. 48. 44. 48. 46. 46. 51. 55. 52. 42. 34. + 169. 171. 170. 165. 160. 154. 144. 133. 117. 97. 78. 77. 93. 113. + 132. 144. 154. 162. 167. 166. 166. 167. 165. 161. 166. 164. 159. + 151. 145. 136. 120. 104. 81. 75. 74. 80. 87. 89. 91. 93. 98. 98. 98. + 99. 99. 100. 100. 100. 101. 101. 102. 103. 105. 107. 108. 110. 116. + 114. 113. 114. 116. 118. 118. 118. 122. 121. 121. 121. 122. 123. + 124. 125. 126. 117. 134. 117. 121. 127. 146. 115. 103. 109. 117. + 122. 122. 120. 121. 122. 125. 122. 120. 122. 127. 132. 134. 134. + 125. 128. 132. 135. 136. 135. 132. 130. 136. 137. 139. 143. 148. + 154. 159. 161. 169. 172. 175. 177. 177. 177. 178. 180. 178. 182. + 184. 184. 186. 189. 190. 188. 188. 190. 193. 195. 197. 198. 198. + 197. 195. 194. 199. 205. 191. 155. 118. 98. 111. 106. 110. 113. 106. + 109. 118. 117. 115. 115. 113. 112. 110. 109. 108. 107. 110. 105. + 102. 102. 104. 108. 118. 128. 139. 143. 149. 152. 153. 151. 150. + 150. 146. 145. 144. 143. 142. 141. 141. 142. 137. 142. 147. 150. + 149. 146. 144. 143. 141. 141. 142. 144. 146. 147. 145. 142. 143. + 142. 142. 141. 142. 142. 143. 144. 142. 142. 143. 144. 145. 145. + 145. 144. 150. 149. 140. 144. 181. 219. 209. 173. 96. 51. 29. 47. + 54. 34. 31. 50. 47. 47. 49. 52. 54. 54. 52. 50. 46. 48. 51. 53. 53. + 49. 44. 41. 46. 46. 52. 61. 56. 40. 27. 25. 172. 173. 169. 162. 156. + 150. 137. 126. 104. 84. 70. 79. 98. 114. 130. 143. 154. 161. 167. + 167. 166. 167. 166. 162. 166. 163. 157. 149. 143. 135. 119. 104. 79. + 74. 74. 81. 88. 90. 91. 93. 100. 100. 100. 100. 100. 100. 100. 100. + 100. 101. 101. 102. 104. 106. 108. 109. 114. 114. 113. 114. 115. + 116. 117. 118. 120. 120. 120. 121. 122. 123. 125. 126. 120. 126. + 116. 129. 123. 137. 116. 108. 116. 118. 120. 120. 119. 119. 121. + 123. 128. 124. 121. 123. 128. 132. 132. 131. 129. 131. 133. 135. + 135. 134. 131. 129. 136. 138. 141. 144. 147. 153. 160. 165. 165. + 168. 171. 173. 173. 173. 175. 176. 178. 181. 184. 186. 189. 191. + 191. 190. 189. 191. 193. 196. 198. 198. 198. 198. 194. 196. 194. + 198. 212. 208. 164. 113. 98. 93. 103. 112. 105. 104. 111. 114. 114. + 113. 112. 111. 110. 109. 108. 107. 111. 106. 102. 102. 103. 107. + 117. 127. 137. 142. 148. 151. 152. 150. 149. 149. 148. 146. 144. + 141. 139. 137. 137. 137. 134. 138. 144. 149. 150. 148. 145. 143. + 142. 142. 142. 144. 146. 147. 145. 142. 142. 142. 142. 142. 142. + 143. 144. 145. 142. 143. 144. 145. 145. 146. 146. 146. 147. 151. + 149. 153. 175. 187. 152. 102. 46. 44. 42. 44. 46. 46. 46. 47. 51. + 49. 48. 50. 53. 52. 48. 43. 46. 51. 56. 56. 52. 47. 44. 43. 44. 50. + 65. 71. 53. 28. 26. 39. 175. 174. 169. 161. 154. 145. 130. 116. 93. + 77. 71. 84. 103. 117. 130. 141. 154. 161. 167. 167. 167. 168. 167. + 163. 165. 163. 157. 149. 143. 134. 119. 104. 79. 74. 74. 81. 88. 91. + 92. 94. 101. 101. 101. 101. 100. 100. 100. 100. 100. 101. 101. 102. + 104. 106. 108. 109. 113. 113. 114. 114. 114. 115. 117. 118. 120. + 120. 120. 120. 121. 123. 124. 125. 119. 132. 110. 132. 146. 136. 96. + 116. 118. 117. 114. 112. 110. 112. 116. 119. 129. 126. 124. 124. + 127. 129. 129. 127. 134. 134. 134. 134. 134. 134. 133. 133. 138. + 139. 141. 143. 145. 150. 156. 160. 164. 166. 168. 170. 172. 175. + 179. 182. 181. 182. 185. 189. 191. 191. 192. 192. 190. 192. 194. + 196. 197. 198. 197. 197. 189. 201. 204. 197. 199. 205. 195. 175. + 123. 93. 81. 91. 98. 103. 106. 103. 113. 112. 111. 110. 109. 108. + 107. 107. 111. 105. 101. 102. 103. 106. 116. 126. 138. 142. 148. + 152. 153. 152. 151. 151. 150. 148. 144. 140. 136. 133. 131. 129. + 130. 134. 140. 147. 150. 149. 146. 143. 143. 143. 143. 145. 147. + 147. 144. 142. 142. 142. 142. 142. 143. 144. 145. 146. 143. 144. + 144. 145. 146. 147. 148. 148. 144. 148. 156. 162. 159. 134. 86. 45. + 35. 51. 54. 40. 38. 51. 56. 49. 55. 52. 49. 49. 50. 49. 44. 40. 50. + 53. 56. 54. 49. 46. 47. 50. 54. 62. 72. 66. 41. 26. 50. 86. 173. + 172. 166. 158. 150. 139. 120. 104. 86. 78. 77. 87. 104. 119. 132. + 140. 154. 161. 167. 167. 167. 169. 167. 164. 164. 163. 157. 150. + 144. 135. 119. 103. 81. 75. 74. 81. 88. 91. 94. 96. 100. 100. 100. + 100. 100. 100. 100. 100. 101. 101. 102. 103. 105. 107. 108. 110. + 113. 114. 115. 114. 114. 114. 117. 119. 121. 120. 120. 120. 121. + 122. 123. 124. 127. 126. 124. 127. 167. 122. 101. 121. 113. 112. + 109. 108. 109. 113. 117. 120. 126. 126. 125. 125. 125. 126. 127. + 127. 134. 134. 133. 133. 134. 134. 135. 136. 138. 137. 138. 140. + 142. 146. 149. 150. 158. 160. 163. 166. 169. 174. 180. 184. 185. + 183. 185. 190. 192. 191. 191. 194. 192. 193. 195. 196. 196. 196. + 195. 194. 197. 195. 196. 196. 190. 186. 196. 213. 187. 152. 129. + 117. 97. 87. 98. 110. 110. 110. 109. 108. 107. 106. 106. 105. 109. + 104. 101. 101. 102. 106. 117. 127. 141. 145. 152. 156. 156. 156. + 155. 155. 151. 150. 146. 141. 135. 129. 124. 121. 124. 127. 133. + 141. 147. 149. 147. 145. 144. 143. 144. 145. 147. 147. 144. 142. + 144. 143. 143. 143. 143. 144. 144. 145. 144. 144. 144. 145. 146. + 147. 149. 150. 151. 153. 160. 158. 133. 89. 53. 36. 42. 46. 46. 41. + 39. 45. 52. 57. 56. 53. 50. 48. 47. 46. 45. 43. 54. 54. 53. 50. 47. + 48. 52. 57. 66. 65. 59. 44. 28. 39. 86. 134. 168. 166. 160. 152. + 144. 130. 109. 90. 83. 83. 83. 86. 98. 118. 134. 140. 154. 161. 167. + 167. 168. 169. 168. 165. 164. 163. 159. 152. 146. 136. 119. 102. 83. + 77. 75. 81. 88. 92. 96. 99. 99. 99. 99. 99. 100. 100. 100. 100. 102. + 102. 103. 104. 105. 107. 109. 110. 113. 115. 116. 116. 114. 114. + 117. 120. 122. 121. 121. 120. 120. 121. 122. 122. 131. 116. 133. + 137. 148. 116. 114. 112. 109. 109. 110. 113. 116. 118. 120. 120. + 119. 123. 126. 126. 123. 123. 127. 131. 129. 130. 132. 134. 135. + 136. 135. 135. 138. 136. 136. 139. 144. 147. 146. 145. 154. 158. + 163. 168. 172. 176. 180. 183. 187. 184. 184. 189. 190. 188. 189. + 194. 193. 194. 195. 195. 195. 194. 192. 191. 196. 188. 186. 193. + 198. 199. 204. 212. 224. 213. 209. 186. 128. 84. 88. 109. 106. 106. + 105. 105. 104. 103. 103. 102. 108. 103. 100. 100. 102. 107. 117. + 128. 141. 146. 152. 156. 157. 157. 156. 156. 153. 151. 148. 142. + 135. 126. 118. 113. 114. 117. 123. 133. 142. 148. 149. 148. 145. + 144. 144. 146. 147. 147. 144. 142. 145. 145. 144. 143. 143. 143. + 144. 144. 145. 145. 144. 145. 146. 148. 150. 151. 156. 159. 158. + 140. 101. 61. 45. 47. 46. 42. 41. 42. 44. 46. 50. 55. 53. 52. 49. + 46. 44. 45. 49. 52. 55. 53. 50. 47. 47. 51. 57. 61. 72. 61. 44. 32. + 39. 74. 123. 160. 163. 161. 156. 148. 139. 124. 101. 81. 83. 88. 86. + 83. 93. 116. 135. 141. 154. 161. 167. 167. 168. 169. 168. 165. 163. + 163. 160. 154. 148. 137. 119. 102. 84. 78. 75. 81. 88. 93. 97. 101. + 98. 98. 98. 99. 99. 100. 100. 100. 103. 103. 103. 105. 106. 108. + 110. 111. 113. 115. 117. 116. 114. 115. 118. 121. 122. 122. 121. + 120. 120. 120. 121. 121. 130. 112. 128. 156. 111. 120. 120. 100. + 104. 106. 110. 115. 119. 119. 116. 114. 113. 120. 125. 125. 122. + 122. 128. 134. 123. 126. 131. 135. 137. 136. 135. 133. 140. 137. + 136. 140. 147. 151. 148. 144. 157. 163. 171. 177. 181. 183. 185. + 186. 188. 183. 183. 187. 188. 185. 188. 194. 194. 194. 195. 195. + 194. 192. 190. 189. 178. 195. 204. 201. 207. 222. 224. 213. 219. + 219. 234. 228. 170. 106. 83. 86. 103. 103. 103. 102. 101. 101. 100. + 100. 107. 102. 99. 100. 102. 107. 118. 129. 139. 144. 150. 155. 156. + 155. 155. 155. 153. 152. 149. 143. 134. 124. 114. 108. 106. 109. + 116. 127. 139. 147. 150. 150. 145. 144. 145. 146. 147. 147. 144. + 142. 146. 146. 145. 144. 143. 143. 143. 143. 145. 145. 144. 145. + 146. 148. 151. 152. 151. 157. 151. 120. 75. 44. 40. 48. 43. 47. 46. + 42. 47. 57. 55. 45. 49. 50. 49. 45. 43. 46. 52. 58. 54. 51. 48. 47. + 49. 54. 59. 63. 77. 61. 41. 39. 67. 114. 152. 170. 158. 159. 156. + 145. 127. 106. 90. 81. 80. 80. 82. 88. 101. 119. 135. 145. 154. 158. + 164. 168. 168. 167. 166. 166. 161. 162. 159. 152. 144. 133. 116. + 101. 79. 74. 72. 79. 87. 90. 93. 97. 98. 98. 99. 99. 99. 99. 99. 99. + 101. 101. 102. 103. 105. 108. 110. 111. 112. 112. 113. 114. 116. + 118. 121. 122. 118. 121. 124. 123. 120. 119. 120. 121. 124. 130. + 133. 127. 115. 107. 108. 112. 109. 111. 114. 115. 115. 116. 117. + 119. 128. 126. 122. 120. 120. 123. 127. 130. 123. 127. 130. 132. + 133. 133. 134. 135. 128. 134. 140. 142. 141. 142. 147. 152. 156. + 158. 167. 174. 177. 185. 187. 179. 180. 184. 187. 187. 185. 185. + 189. 193. 197. 193. 188. 185. 185. 187. 192. 195. 210. 209. 209. + 210. 211. 212. 214. 214. 218. 216. 221. 239. 219. 139. 81. 87. 84. + 104. 105. 100. 105. 97. 93. 109. 100. 100. 100. 99. 101. 108. 120. + 129. 138. 143. 150. 154. 155. 154. 153. 153. 151. 151. 149. 144. + 138. 128. 109. 92. 94. 92. 100. 118. 130. 135. 142. 151. 147. 145. + 142. 143. 146. 147. 146. 144. 143. 143. 143. 144. 144. 145. 145. + 145. 144. 144. 146. 149. 148. 145. 146. 150. 159. 154. 125. 81. 49. + 43. 47. 47. 42. 44. 47. 49. 51. 52. 52. 52. 49. 53. 50. 41. 41. 52. + 58. 56. 40. 49. 52. 45. 44. 56. 72. 80. 79. 50. 37. 65. 111. 144. + 160. 166. 157. 156. 150. 136. 117. 99. 86. 81. 83. 82. 83. 89. 101. + 118. 135. 145. 153. 158. 164. 168. 168. 167. 166. 166. 163. 163. + 159. 151. 143. 132. 116. 102. 82. 76. 74. 81. 88. 91. 94. 97. 98. + 98. 99. 99. 100. 100. 101. 101. 101. 101. 102. 103. 105. 108. 110. + 111. 114. 114. 114. 115. 116. 117. 119. 120. 119. 122. 123. 123. + 121. 120. 121. 123. 127. 128. 127. 119. 110. 106. 109. 114. 112. + 115. 117. 119. 119. 119. 121. 122. 118. 119. 121. 122. 122. 122. + 122. 121. 123. 126. 130. 131. 131. 131. 132. 133. 134. 137. 140. + 140. 138. 139. 145. 150. 151. 167. 165. 165. 185. 188. 181. 188. + 191. 187. 182. 183. 187. 191. 192. 192. 183. 181. 179. 181. 187. + 198. 209. 216. 212. 211. 210. 210. 210. 210. 210. 211. 208. 219. + 220. 222. 223. 192. 125. 71. 87. 98. 97. 92. 99. 104. 101. 100. 99. + 99. 98. 97. 99. 106. 118. 127. 138. 143. 150. 154. 155. 154. 153. + 153. 153. 153. 150. 145. 138. 127. 108. 91. 81. 80. 90. 111. 128. + 135. 140. 148. 149. 146. 143. 143. 145. 147. 146. 144. 143. 143. + 143. 144. 144. 145. 145. 145. 145. 145. 146. 148. 147. 147. 150. + 155. 157. 133. 92. 54. 36. 35. 37. 36. 45. 46. 49. 51. 52. 53. 53. + 52. 51. 49. 46. 44. 48. 54. 55. 51. 43. 48. 49. 48. 52. 63. 71. 73. + 63. 56. 66. 99. 133. 149. 155. 159. 156. 152. 141. 123. 102. 88. 82. + 82. 86. 85. 85. 90. 102. 118. 134. 144. 153. 158. 164. 167. 168. + 167. 166. 166. 164. 164. 158. 149. 141. 132. 117. 103. 84. 78. 76. + 82. 89. 92. 94. 97. 98. 98. 99. 100. 101. 102. 103. 103. 101. 101. + 102. 103. 105. 108. 110. 111. 116. 116. 115. 115. 115. 116. 117. + 118. 120. 122. 123. 122. 121. 122. 124. 126. 128. 125. 118. 110. + 105. 105. 110. 115. 114. 116. 119. 120. 121. 121. 123. 124. 116. + 117. 118. 119. 120. 121. 121. 121. 129. 132. 135. 136. 136. 135. + 135. 136. 135. 138. 139. 139. 138. 140. 146. 151. 163. 151. 167. + 177. 167. 182. 196. 177. 183. 186. 191. 194. 192. 186. 179. 174. + 171. 178. 190. 201. 209. 212. 211. 210. 211. 210. 209. 209. 208. + 209. 209. 210. 209. 219. 221. 215. 227. 234. 179. 98. 83. 86. 92. + 93. 93. 103. 105. 93. 97. 98. 97. 96. 97. 104. 116. 124. 138. 143. + 150. 154. 155. 154. 153. 153. 155. 155. 152. 146. 139. 127. 107. 90. + 67. 64. 74. 99. 122. 132. 137. 143. 150. 148. 145. 144. 145. 146. + 146. 145. 143. 143. 143. 144. 144. 145. 145. 145. 143. 144. 145. + 144. 145. 149. 154. 157. 154. 113. 65. 41. 39. 43. 45. 44. 48. 49. + 51. 53. 54. 54. 53. 53. 51. 44. 43. 49. 55. 54. 49. 46. 48. 50. 51. + 55. 64. 72. 71. 66. 59. 73. 103. 135. 150. 150. 150. 155. 153. 145. + 130. 109. 90. 80. 81. 85. 89. 87. 87. 90. 101. 117. 133. 144. 153. + 157. 163. 167. 168. 166. 166. 166. 166. 164. 158. 148. 140. 131. + 117. 104. 85. 79. 77. 82. 89. 91. 93. 96. 97. 98. 99. 100. 102. 103. + 104. 105. 101. 101. 102. 103. 105. 108. 110. 111. 115. 115. 115. + 115. 116. 117. 118. 119. 121. 122. 122. 122. 122. 124. 126. 127. + 125. 119. 110. 104. 103. 107. 111. 114. 113. 115. 118. 119. 119. + 119. 121. 122. 122. 119. 116. 114. 116. 121. 127. 130. 132. 135. + 138. 139. 138. 137. 137. 138. 133. 136. 139. 141. 142. 145. 150. + 153. 151. 173. 161. 155. 181. 181. 168. 184. 177. 187. 194. 190. + 177. 168. 168. 173. 190. 198. 209. 217. 218. 212. 202. 195. 207. + 207. 207. 207. 207. 208. 209. 210. 212. 208. 216. 219. 219. 229. + 211. 163. 91. 78. 87. 98. 91. 94. 101. 93. 97. 97. 96. 95. 96. 104. + 115. 124. 138. 143. 150. 154. 155. 154. 153. 153. 154. 155. 152. + 146. 140. 129. 110. 92. 61. 53. 59. 84. 111. 125. 133. 138. 150. + 148. 146. 145. 145. 145. 145. 146. 143. 143. 143. 144. 144. 145. + 145. 145. 140. 143. 143. 141. 145. 153. 155. 152. 115. 77. 42. 34. + 39. 40. 41. 45. 52. 53. 54. 55. 55. 54. 53. 52. 48. 42. 45. 56. 59. + 51. 44. 45. 51. 54. 59. 65. 72. 75. 72. 67. 79. 100. 130. 151. 151. + 144. 145. 153. 147. 136. 118. 98. 84. 80. 84. 89. 91. 89. 87. 90. + 100. 116. 133. 143. 152. 157. 163. 167. 167. 166. 165. 165. 166. + 165. 158. 149. 140. 131. 116. 103. 84. 78. 76. 81. 88. 90. 92. 95. + 97. 98. 99. 100. 102. 103. 104. 105. 101. 101. 102. 103. 105. 108. + 110. 111. 112. 113. 113. 114. 116. 118. 120. 121. 121. 121. 121. + 122. 123. 125. 126. 126. 117. 112. 107. 105. 107. 109. 111. 111. + 114. 116. 119. 119. 118. 118. 119. 120. 119. 118. 116. 116. 118. + 123. 128. 131. 129. 132. 135. 135. 135. 134. 134. 134. 135. 138. + 142. 144. 146. 147. 149. 150. 162. 148. 165. 176. 161. 176. 192. + 169. 187. 182. 173. 162. 159. 168. 186. 200. 218. 216. 211. 207. + 204. 203. 203. 203. 207. 206. 206. 205. 205. 206. 207. 207. 207. + 200. 211. 218. 211. 219. 223. 207. 137. 88. 72. 87. 89. 89. 96. 95. + 96. 96. 96. 95. 97. 104. 116. 125. 138. 143. 150. 154. 155. 154. + 153. 153. 152. 153. 151. 146. 141. 131. 113. 96. 64. 51. 48. 69. 96. + 114. 126. 134. 147. 147. 147. 146. 145. 145. 145. 145. 143. 143. + 143. 144. 144. 145. 145. 145. 140. 145. 146. 143. 150. 158. 152. + 137. 78. 57. 45. 49. 49. 40. 41. 51. 54. 54. 55. 55. 54. 53. 51. 49. + 45. 44. 51. 60. 57. 46. 42. 48. 50. 56. 64. 71. 73. 72. 74. 77. 107. + 123. 144. 153. 147. 139. 140. 147. 138. 125. 106. 90. 83. 84. 88. + 91. 91. 88. 86. 89. 99. 115. 132. 143. 152. 157. 163. 166. 167. 166. + 165. 165. 166. 165. 159. 150. 141. 131. 115. 101. 83. 77. 75. 81. + 88. 91. 93. 96. 98. 98. 99. 100. 101. 102. 103. 103. 101. 101. 102. + 103. 105. 108. 110. 111. 112. 112. 113. 114. 116. 119. 121. 122. + 121. 120. 121. 122. 125. 125. 124. 122. 109. 108. 107. 108. 110. + 112. 112. 111. 117. 119. 121. 120. 118. 117. 117. 118. 109. 112. + 118. 123. 126. 127. 125. 124. 130. 133. 136. 138. 137. 136. 137. + 138. 143. 144. 144. 145. 145. 145. 144. 144. 145. 167. 161. 160. + 184. 183. 170. 181. 178. 167. 158. 162. 179. 196. 206. 209. 209. + 208. 206. 205. 204. 204. 205. 206. 207. 206. 205. 204. 204. 203. + 204. 204. 205. 208. 214. 214. 216. 230. 232. 217. 199. 125. 70. 70. + 84. 90. 92. 93. 93. 94. 94. 94. 96. 105. 117. 127. 138. 143. 150. + 154. 155. 154. 153. 153. 151. 152. 151. 147. 142. 133. 115. 98. 68. + 51. 43. 58. 82. 102. 118. 130. 142. 144. 147. 148. 146. 144. 144. + 144. 143. 143. 143. 144. 144. 145. 145. 145. 143. 150. 151. 148. + 156. 160. 138. 108. 59. 55. 58. 64. 58. 46. 46. 56. 55. 55. 55. 54. + 53. 50. 48. 46. 45. 50. 56. 58. 52. 44. 45. 50. 47. 54. 65. 71. 71. + 73. 84. 97. 126. 137. 150. 153. 147. 140. 140. 143. 128. 113. 94. + 84. 85. 89. 92. 91. 90. 87. 85. 87. 98. 114. 132. 143. 152. 156. + 162. 166. 166. 165. 165. 164. 165. 165. 160. 151. 142. 131. 114. + 100. 83. 77. 76. 82. 89. 93. 95. 98. 98. 98. 99. 99. 100. 100. 101. + 101. 101. 101. 102. 103. 105. 108. 110. 111. 113. 113. 114. 114. + 116. 118. 119. 120. 120. 120. 120. 123. 126. 125. 121. 117. 105. + 107. 109. 111. 112. 113. 114. 114. 118. 119. 120. 119. 116. 113. + 113. 113. 107. 112. 120. 127. 131. 130. 128. 125. 134. 137. 140. + 142. 142. 142. 143. 144. 148. 146. 142. 140. 139. 141. 142. 143. + 151. 148. 165. 175. 169. 176. 179. 160. 157. 163. 175. 192. 207. + 212. 206. 199. 194. 200. 207. 212. 213. 208. 202. 197. 201. 201. + 201. 202. 203. 205. 207. 208. 209. 217. 214. 212. 222. 228. 225. + 224. 228. 174. 106. 74. 78. 83. 83. 89. 89. 90. 91. 92. 95. 104. + 117. 127. 138. 143. 150. 154. 155. 154. 153. 153. 153. 154. 152. + 148. 143. 133. 114. 98. 67. 49. 40. 51. 72. 92. 110. 125. 136. 141. + 146. 149. 147. 144. 143. 143. 143. 143. 143. 144. 144. 145. 145. + 145. 144. 152. 152. 149. 156. 154. 115. 69. 41. 41. 45. 49. 46. 40. + 42. 49. 54. 54. 54. 53. 51. 47. 44. 42. 50. 55. 57. 52. 48. 49. 50. + 50. 51. 54. 63. 71. 75. 84. 103. 122. 137. 145. 150. 149. 144. 143. + 148. 153. 120. 105. 87. 81. 86. 93. 93. 91. 89. 86. 84. 86. 97. 114. + 132. 143. 152. 156. 162. 166. 166. 165. 164. 164. 164. 164. 160. + 152. 143. 131. 114. 98. 83. 78. 77. 83. 91. 95. 97. 101. 98. 98. 99. + 99. 99. 99. 99. 99. 101. 101. 102. 103. 105. 108. 110. 111. 116. + 115. 115. 115. 115. 116. 117. 118. 119. 119. 120. 124. 126. 125. + 119. 114. 104. 107. 110. 111. 112. 113. 115. 118. 115. 117. 117. + 115. 112. 109. 108. 108. 115. 118. 122. 126. 130. 133. 134. 134. + 131. 135. 138. 140. 141. 141. 142. 143. 149. 143. 137. 133. 134. + 139. 144. 147. 146. 158. 164. 166. 173. 169. 157. 150. 153. 175. + 200. 210. 206. 199. 198. 201. 207. 208. 208. 208. 206. 203. 200. + 199. 192. 193. 196. 200. 204. 209. 213. 216. 211. 213. 206. 209. + 217. 204. 205. 234. 225. 209. 151. 92. 74. 71. 72. 86. 86. 87. 88. + 89. 94. 103. 117. 127. 138. 143. 150. 154. 155. 154. 153. 153. 156. + 156. 153. 148. 142. 132. 113. 96. 64. 48. 38. 49. 68. 86. 105. 121. + 132. 138. 146. 149. 148. 144. 143. 142. 143. 143. 143. 144. 144. + 145. 145. 145. 143. 151. 150. 147. 153. 145. 96. 40. 44. 41. 39. 42. + 46. 50. 54. 58. 54. 54. 53. 52. 49. 46. 42. 40. 55. 59. 55. 46. 46. + 53. 54. 48. 56. 57. 62. 72. 82. 96. 120. 142. 145. 149. 149. 142. + 138. 145. 158. 169. 98. 90. 81. 82. 89. 94. 91. 86. 92. 89. 87. 89. + 98. 114. 130. 140. 148. 156. 162. 163. 165. 168. 168. 166. 165. 165. + 159. 150. 142. 133. 118. 104. 86. 79. 77. 84. 92. 95. 95. 96. 102. + 100. 98. 97. 96. 98. 100. 101. 99. 99. 100. 101. 103. 106. 108. 109. + 112. 116. 119. 120. 117. 116. 117. 118. 118. 126. 125. 123. 128. + 124. 117. 118. 118. 114. 111. 109. 110. 113. 114. 115. 118. 116. + 114. 114. 116. 117. 117. 116. 124. 122. 123. 128. 134. 136. 134. + 130. 134. 134. 134. 135. 138. 141. 144. 145. 145. 141. 137. 137. + 141. 145. 147. 147. 160. 148. 159. 179. 165. 133. 137. 169. 192. + 199. 204. 204. 204. 207. 207. 204. 204. 204. 203. 201. 199. 198. + 197. 196. 205. 205. 204. 203. 202. 202. 201. 201. 200. 201. 204. + 207. 209. 211. 211. 211. 215. 222. 209. 167. 117. 85. 75. 74. 81. + 73. 94. 92. 85. 106. 119. 127. 138. 145. 153. 156. 156. 154. 153. + 154. 151. 154. 155. 152. 146. 134. 115. 98. 72. 48. 40. 50. 61. 78. + 98. 105. 124. 131. 141. 147. 148. 146. 143. 141. 140. 135. 136. 143. + 147. 144. 144. 148. 148. 146. 154. 162. 145. 103. 62. 43. 39. 38. + 39. 44. 51. 56. 58. 57. 55. 52. 48. 44. 43. 45. 49. 53. 62. 49. 45. + 54. 55. 48. 48. 57. 64. 64. 60. 72. 102. 124. 135. 145. 148. 146. + 144. 143. 145. 152. 160. 166. 95. 89. 84. 84. 90. 93. 91. 88. 92. + 89. 86. 88. 98. 113. 129. 140. 148. 156. 162. 163. 164. 168. 168. + 166. 164. 164. 159. 150. 142. 132. 117. 104. 86. 78. 75. 82. 90. 93. + 94. 96. 100. 100. 99. 98. 98. 98. 99. 100. 100. 100. 101. 102. 104. + 107. 109. 110. 112. 116. 119. 120. 118. 117. 118. 119. 123. 116. + 119. 130. 131. 118. 111. 116. 115. 114. 112. 111. 111. 112. 114. + 115. 118. 116. 115. 115. 117. 119. 119. 118. 122. 124. 126. 127. + 128. 129. 130. 132. 137. 137. 137. 137. 138. 139. 141. 142. 141. + 138. 134. 135. 139. 142. 144. 144. 148. 165. 170. 152. 137. 147. + 171. 188. 192. 198. 200. 199. 200. 204. 207. 206. 200. 200. 200. + 200. 199. 199. 199. 199. 201. 201. 201. 201. 202. 202. 202. 202. + 204. 205. 208. 210. 212. 212. 212. 212. 223. 215. 220. 228. 200. + 140. 88. 68. 72. 76. 86. 78. 88. 110. 111. 121. 138. 144. 152. 156. + 155. 154. 153. 154. 151. 154. 155. 152. 145. 134. 115. 98. 69. 49. + 41. 46. 47. 61. 84. 96. 120. 127. 138. 144. 146. 145. 144. 144. 150. + 143. 140. 143. 145. 142. 142. 145. 149. 149. 156. 155. 125. 77. 46. + 40. 39. 39. 41. 46. 52. 56. 57. 56. 56. 55. 51. 45. 42. 45. 53. 59. + 56. 47. 45. 51. 55. 53. 54. 59. 60. 64. 65. 82. 115. 136. 141. 148. + 150. 147. 145. 147. 154. 161. 164. 165. 89. 88. 87. 88. 90. 92. 91. + 90. 92. 89. 86. 88. 98. 113. 129. 140. 149. 156. 162. 163. 164. 167. + 167. 165. 163. 163. 158. 149. 141. 132. 116. 102. 86. 78. 73. 79. + 87. 91. 93. 95. 98. 99. 99. 100. 100. 99. 99. 99. 101. 101. 102. + 103. 105. 108. 110. 111. 112. 115. 118. 120. 119. 118. 119. 120. + 126. 109. 118. 137. 129. 109. 105. 111. 110. 113. 115. 114. 111. + 110. 112. 115. 117. 115. 114. 115. 118. 120. 121. 120. 124. 128. + 130. 129. 126. 127. 132. 137. 140. 140. 140. 139. 139. 138. 138. + 138. 135. 133. 133. 135. 138. 141. 142. 142. 142. 157. 152. 134. + 146. 185. 201. 190. 193. 197. 197. 194. 194. 200. 205. 205. 198. + 198. 198. 198. 199. 199. 199. 199. 199. 199. 201. 202. 204. 205. + 206. 207. 207. 208. 209. 210. 211. 211. 211. 211. 213. 216. 219. + 225. 230. 210. 152. 95. 62. 73. 83. 73. 86. 106. 106. 124. 137. 144. + 152. 156. 155. 154. 153. 155. 151. 154. 155. 151. 145. 133. 115. 99. + 69. 51. 45. 43. 35. 43. 67. 82. 107. 117. 131. 141. 145. 146. 148. + 149. 147. 141. 138. 140. 143. 143. 146. 149. 149. 154. 155. 136. 92. + 49. 35. 41. 40. 41. 44. 49. 54. 56. 56. 54. 58. 56. 52. 46. 44. 47. + 56. 63. 48. 46. 46. 49. 55. 58. 58. 57. 55. 67. 79. 102. 133. 147. + 146. 149. 147. 145. 146. 153. 163. 168. 166. 161. 85. 87. 90. 91. + 91. 91. 91. 92. 93. 90. 87. 89. 99. 114. 130. 141. 149. 156. 162. + 162. 164. 166. 167. 164. 162. 162. 157. 149. 141. 131. 115. 101. 88. + 79. 74. 78. 86. 90. 93. 96. 96. 97. 99. 101. 101. 100. 99. 98. 100. + 101. 101. 103. 105. 107. 109. 111. 113. 115. 117. 119. 120. 119. + 119. 119. 120. 115. 129. 137. 118. 103. 104. 105. 107. 112. 116. + 116. 111. 109. 111. 115. 115. 113. 113. 115. 118. 121. 121. 121. + 131. 132. 133. 133. 132. 135. 140. 144. 140. 140. 141. 141. 140. + 139. 138. 137. 131. 132. 134. 137. 139. 140. 139. 138. 132. 135. + 142. 157. 182. 203. 202. 191. 193. 196. 196. 192. 191. 195. 198. + 198. 197. 197. 198. 198. 198. 198. 198. 198. 202. 203. 204. 205. + 207. 208. 209. 210. 207. 207. 208. 208. 208. 208. 207. 207. 210. + 216. 207. 198. 217. 236. 206. 155. 73. 60. 77. 81. 78. 94. 110. 131. + 136. 143. 151. 155. 155. 153. 154. 155. 152. 155. 155. 151. 144. + 133. 115. 99. 72. 54. 47. 44. 35. 38. 56. 67. 91. 104. 123. 137. + 144. 147. 150. 152. 144. 141. 140. 141. 144. 147. 149. 150. 150. + 157. 146. 105. 61. 38. 39. 45. 41. 44. 48. 52. 55. 56. 54. 53. 57. + 53. 48. 47. 49. 53. 57. 58. 43. 48. 50. 50. 54. 58. 56. 50. 54. 79. + 103. 126. 147. 149. 142. 145. 141. 144. 150. 159. 166. 168. 164. + 159. 84. 87. 91. 93. 92. 91. 91. 92. 94. 91. 89. 91. 100. 116. 132. + 142. 149. 156. 162. 162. 163. 166. 166. 163. 161. 161. 158. 150. + 142. 131. 115. 100. 89. 80. 75. 79. 87. 91. 94. 96. 95. 97. 99. 102. + 102. 101. 99. 97. 99. 99. 100. 101. 104. 106. 108. 109. 113. 114. + 116. 118. 119. 119. 118. 117. 112. 135. 147. 127. 103. 102. 107. + 101. 105. 111. 116. 116. 112. 109. 111. 115. 114. 112. 112. 114. + 118. 120. 121. 121. 134. 132. 132. 134. 139. 143. 144. 144. 136. + 138. 140. 141. 141. 140. 138. 137. 132. 133. 135. 136. 135. 133. + 132. 131. 129. 144. 168. 187. 192. 190. 195. 203. 192. 197. 197. + 193. 190. 191. 191. 189. 193. 193. 195. 197. 199. 201. 202. 203. + 205. 205. 206. 206. 207. 207. 208. 208. 208. 208. 207. 206. 206. + 206. 206. 206. 218. 211. 208. 216. 223. 220. 210. 202. 116. 50. 61. + 84. 72. 91. 117. 124. 135. 142. 150. 155. 155. 153. 154. 155. 152. + 155. 155. 150. 144. 133. 116. 100. 73. 53. 45. 46. 40. 41. 49. 51. + 77. 94. 116. 132. 140. 142. 145. 148. 146. 145. 144. 143. 145. 147. + 147. 145. 154. 156. 127. 73. 40. 41. 48. 45. 44. 47. 51. 54. 56. 55. + 54. 53. 56. 49. 44. 47. 55. 59. 54. 48. 44. 51. 55. 52. 51. 52. 51. + 48. 66. 99. 129. 146. 152. 142. 134. 139. 139. 147. 158. 165. 166. + 164. 162. 162. 86. 89. 91. 92. 92. 91. 91. 92. 94. 91. 88. 90. 100. + 116. 132. 142. 149. 156. 162. 162. 162. 165. 165. 162. 161. 162. + 159. 151. 143. 132. 115. 100. 89. 80. 76. 81. 88. 91. 93. 95. 95. + 96. 99. 101. 102. 101. 100. 98. 98. 99. 99. 101. 103. 105. 108. 109. + 114. 114. 114. 116. 118. 118. 116. 113. 113. 160. 160. 113. 94. 105. + 107. 101. 106. 110. 114. 114. 112. 111. 112. 114. 115. 114. 113. + 115. 118. 121. 122. 122. 131. 130. 130. 135. 142. 144. 142. 138. + 133. 135. 138. 141. 142. 140. 138. 136. 134. 133. 131. 128. 126. + 127. 130. 133. 160. 177. 188. 184. 183. 192. 198. 197. 192. 196. + 197. 192. 189. 189. 188. 186. 187. 189. 192. 196. 201. 205. 208. + 210. 204. 204. 204. 204. 204. 204. 204. 203. 210. 209. 208. 207. + 206. 206. 207. 207. 205. 214. 220. 218. 214. 215. 219. 221. 174. 73. + 54. 73. 72. 96. 116. 112. 134. 141. 150. 154. 154. 153. 154. 155. + 153. 155. 154. 149. 143. 133. 116. 101. 74. 50. 41. 45. 43. 42. 44. + 39. 65. 82. 105. 121. 128. 133. 138. 143. 136. 137. 136. 135. 139. + 146. 148. 146. 155. 139. 98. 52. 34. 44. 49. 43. 47. 50. 54. 55. 55. + 54. 53. 54. 53. 47. 44. 49. 57. 59. 51. 42. 49. 53. 56. 53. 47. 46. + 52. 60. 90. 122. 146. 154. 149. 135. 130. 140. 145. 154. 165. 168. + 165. 162. 163. 166. 90. 90. 90. 91. 92. 92. 91. 90. 92. 89. 86. 89. + 98. 114. 130. 140. 149. 156. 162. 162. 162. 164. 164. 162. 162. 163. + 160. 153. 145. 133. 116. 101. 87. 79. 75. 81. 88. 90. 91. 92. 95. + 96. 98. 100. 101. 101. 100. 100. 99. 100. 100. 102. 104. 106. 108. + 110. 115. 113. 113. 114. 116. 116. 113. 110. 124. 180. 161. 100. 96. + 110. 104. 104. 108. 109. 110. 111. 112. 112. 113. 113. 118. 117. + 116. 118. 121. 123. 124. 123. 127. 130. 135. 139. 141. 139. 135. + 131. 131. 134. 138. 141. 141. 139. 136. 133. 132. 129. 123. 118. + 120. 131. 146. 157. 187. 194. 190. 180. 183. 196. 196. 183. 192. + 195. 194. 188. 186. 188. 190. 189. 190. 191. 194. 198. 201. 205. + 208. 209. 203. 203. 203. 203. 203. 203. 203. 203. 208. 207. 206. + 205. 204. 205. 206. 206. 193. 214. 220. 206. 203. 220. 230. 224. + 213. 134. 81. 61. 71. 94. 103. 118. 133. 140. 149. 154. 154. 153. + 154. 155. 154. 155. 154. 149. 143. 133. 116. 101. 77. 53. 43. 46. + 43. 41. 42. 37. 48. 64. 86. 103. 114. 125. 139. 149. 145. 144. 139. + 134. 137. 147. 152. 151. 146. 105. 62. 43. 41. 41. 42. 46. 51. 53. + 56. 56. 54. 52. 53. 55. 51. 49. 48. 51. 54. 54. 49. 45. 55. 54. 54. + 51. 42. 41. 61. 85. 120. 140. 151. 148. 143. 134. 134. 147. 154. + 159. 164. 165. 162. 161. 162. 164. 93. 91. 90. 90. 92. 92. 91. 89. + 90. 87. 85. 87. 96. 112. 128. 138. 149. 156. 161. 162. 162. 164. + 164. 161. 162. 163. 160. 154. 146. 134. 117. 101. 85. 77. 74. 80. + 87. 89. 89. 89. 96. 97. 98. 99. 100. 101. 101. 101. 101. 101. 102. + 103. 105. 108. 110. 111. 115. 113. 112. 113. 115. 115. 111. 107. + 135. 189. 157. 93. 101. 112. 100. 108. 110. 109. 108. 110. 112. 114. + 113. 112. 121. 120. 119. 120. 123. 125. 125. 125. 125. 133. 142. + 145. 141. 135. 130. 129. 132. 134. 138. 141. 141. 137. 133. 130. + 129. 123. 116. 112. 120. 140. 166. 184. 178. 190. 200. 198. 187. + 180. 181. 187. 192. 193. 191. 185. 183. 188. 193. 194. 197. 197. + 198. 199. 201. 202. 203. 204. 204. 204. 204. 205. 205. 206. 206. + 206. 205. 204. 202. 201. 201. 202. 203. 204. 206. 200. 208. 224. + 226. 214. 213. 224. 226. 191. 119. 59. 69. 85. 91. 136. 133. 140. + 149. 154. 154. 153. 154. 155. 154. 155. 154. 149. 142. 132. 116. + 101. 82. 58. 48. 48. 42. 40. 43. 41. 33. 49. 70. 89. 105. 123. 144. + 160. 179. 174. 161. 146. 143. 149. 153. 151. 134. 75. 35. 42. 50. + 37. 36. 53. 53. 55. 57. 56. 53. 51. 53. 56. 51. 53. 54. 53. 50. 48. + 49. 51. 59. 54. 51. 49. 39. 40. 70. 106. 140. 151. 149. 141. 139. + 136. 140. 154. 160. 159. 158. 158. 159. 159. 159. 158. 92. 92. 91. + 90. 90. 91. 91. 92. 87. 85. 84. 86. 95. 112. 131. 144. 150. 154. + 160. 164. 164. 163. 162. 162. 165. 166. 162. 154. 146. 136. 120. + 105. 90. 76. 75. 84. 87. 92. 96. 91. 93. 94. 97. 99. 101. 102. 103. + 103. 100. 102. 104. 107. 109. 109. 109. 109. 103. 123. 110. 116. + 106. 117. 105. 113. 192. 181. 131. 97. 108. 105. 94. 109. 112. 112. + 109. 107. 108. 112. 114. 112. 114. 118. 122. 123. 122. 122. 125. + 128. 133. 137. 137. 134. 134. 138. 137. 132. 144. 132. 130. 141. + 145. 135. 126. 126. 130. 102. 100. 132. 164. 184. 188. 180. 182. + 192. 196. 189. 182. 184. 187. 188. 182. 178. 177. 184. 194. 201. + 200. 196. 193. 195. 197. 195. 194. 197. 204. 210. 204. 204. 204. + 205. 206. 205. 203. 201. 200. 200. 201. 202. 204. 207. 209. 210. + 204. 207. 209. 210. 209. 212. 217. 221. 223. 218. 195. 58. 67. 84. + 97. 123. 131. 141. 149. 150. 149. 152. 152. 151. 154. 155. 154. 150. + 146. 136. 117. 100. 75. 53. 41. 48. 50. 40. 38. 46. 40. 39. 45. 68. + 115. 176. 208. 205. 216. 218. 203. 183. 186. 196. 174. 137. 85. 48. + 49. 27. 50. 50. 39. 58. 59. 56. 52. 53. 56. 58. 58. 57. 48. 52. 55. + 51. 46. 45. 51. 58. 53. 53. 49. 42. 43. 64. 100. 128. 144. 145. 143. + 140. 138. 142. 152. 160. 161. 161. 161. 160. 160. 159. 159. 159. 92. + 91. 90. 90. 90. 90. 91. 91. 87. 85. 84. 86. 95. 111. 130. 143. 150. + 154. 160. 164. 164. 163. 162. 162. 165. 165. 161. 153. 145. 135. + 119. 104. 88. 74. 74. 82. 85. 90. 95. 90. 93. 94. 95. 97. 99. 100. + 100. 100. 100. 101. 104. 106. 108. 108. 108. 108. 106. 119. 111. + 113. 106. 113. 101. 133. 199. 180. 127. 95. 109. 110. 100. 110. 107. + 108. 112. 116. 117. 114. 110. 108. 114. 115. 118. 120. 122. 126. + 131. 135. 135. 127. 133. 148. 146. 130. 127. 138. 124. 143. 150. + 136. 121. 119. 121. 118. 117. 121. 138. 154. 163. 179. 192. 189. + 183. 182. 180. 183. 192. 197. 188. 174. 177. 177. 179. 184. 189. + 194. 195. 196. 199. 197. 195. 194. 196. 198. 200. 201. 206. 204. + 201. 200. 200. 200. 200. 200. 202. 202. 202. 203. 205. 207. 209. + 210. 207. 209. 211. 211. 210. 212. 217. 221. 227. 224. 205. 97. 52. + 77. 104. 115. 133. 143. 151. 152. 152. 154. 155. 154. 152. 154. 153. + 149. 145. 135. 117. 99. 74. 59. 49. 49. 48. 42. 37. 37. 33. 38. 59. + 121. 191. 209. 205. 219. 192. 201. 202. 201. 212. 220. 201. 171. 62. + 32. 53. 37. 49. 51. 43. 52. 58. 56. 53. 54. 56. 57. 56. 54. 51. 52. + 53. 50. 47. 48. 53. 58. 53. 49. 45. 47. 61. 89. 123. 147. 149. 145. + 139. 138. 143. 151. 158. 162. 161. 161. 160. 160. 160. 159. 159. + 159. 91. 90. 89. 89. 89. 90. 90. 91. 88. 86. 84. 85. 94. 110. 128. + 141. 150. 154. 160. 164. 165. 164. 163. 163. 164. 164. 160. 152. + 144. 133. 117. 103. 85. 71. 72. 80. 81. 87. 93. 89. 93. 93. 95. 96. + 97. 97. 97. 97. 99. 100. 102. 104. 106. 107. 107. 107. 109. 112. + 112. 108. 107. 107. 99. 165. 198. 172. 118. 90. 104. 108. 100. 107. + 108. 107. 111. 120. 121. 113. 109. 111. 117. 116. 116. 118. 124. + 130. 134. 136. 138. 130. 134. 145. 141. 127. 127. 139. 132. 142. + 140. 124. 114. 116. 116. 109. 121. 145. 173. 177. 170. 181. 194. + 189. 181. 175. 170. 175. 188. 196. 188. 175. 180. 183. 187. 190. + 190. 192. 196. 200. 201. 197. 193. 194. 197. 199. 197. 194. 201. + 200. 197. 195. 196. 198. 201. 203. 204. 204. 204. 204. 205. 206. + 208. 208. 208. 209. 209. 209. 209. 210. 213. 216. 226. 227. 217. + 150. 53. 67. 106. 110. 132. 142. 150. 152. 153. 155. 156. 154. 152. + 153. 152. 149. 144. 135. 116. 99. 76. 59. 43. 40. 44. 44. 40. 36. + 38. 51. 130. 211. 224. 216. 211. 195. 196. 205. 213. 220. 229. 232. + 218. 200. 68. 25. 55. 45. 43. 48. 51. 51. 57. 56. 55. 55. 56. 55. + 53. 51. 54. 52. 50. 49. 49. 51. 54. 57. 50. 42. 38. 51. 80. 115. + 142. 155. 152. 143. 136. 139. 151. 161. 165. 163. 161. 160. 160. + 160. 159. 159. 159. 159. 90. 89. 89. 89. 89. 90. 91. 91. 89. 87. 85. + 85. 93. 109. 127. 139. 150. 154. 160. 164. 165. 164. 164. 164. 163. + 163. 159. 151. 143. 132. 116. 101. 82. 69. 70. 77. 78. 84. 91. 89. + 94. 95. 96. 97. 97. 97. 96. 96. 99. 99. 101. 103. 104. 106. 106. + 107. 112. 108. 113. 105. 107. 103. 107. 195. 192. 163. 116. 92. 101. + 104. 100. 106. 115. 108. 109. 117. 116. 109. 111. 120. 121. 119. + 118. 122. 127. 131. 131. 130. 137. 140. 135. 123. 123. 134. 137. + 132. 147. 131. 120. 120. 117. 111. 116. 129. 152. 163. 181. 184. + 177. 182. 187. 179. 177. 177. 175. 171. 170. 176. 184. 190. 185. + 187. 190. 192. 192. 194. 196. 199. 197. 195. 193. 194. 196. 197. + 195. 192. 194. 194. 195. 196. 198. 201. 206. 209. 204. 204. 203. + 203. 203. 204. 205. 206. 206. 206. 206. 205. 205. 206. 208. 209. + 218. 227. 225. 189. 92. 62. 96. 113. 128. 138. 148. 150. 151. 153. + 154. 152. 153. 154. 153. 149. 145. 135. 116. 99. 73. 53. 40. 42. 45. + 39. 36. 40. 76. 160. 208. 213. 216. 198. 184. 204. 220. 221. 223. + 226. 228. 228. 224. 220. 121. 35. 49. 47. 40. 44. 56. 56. 56. 56. + 56. 56. 55. 53. 50. 48. 56. 52. 48. 48. 51. 54. 56. 55. 49. 41. 42. + 65. 103. 136. 150. 151. 146. 141. 139. 146. 157. 165. 166. 164. 160. + 160. 160. 159. 159. 159. 158. 158. 90. 89. 89. 89. 90. 90. 92. 92. + 91. 89. 86. 86. 93. 108. 126. 138. 149. 154. 161. 165. 166. 165. + 165. 165. 164. 164. 159. 151. 142. 131. 115. 100. 81. 68. 69. 76. + 76. 82. 91. 90. 97. 97. 98. 99. 99. 98. 98. 97. 99. 99. 100. 102. + 103. 105. 106. 107. 113. 107. 114. 104. 107. 101. 127. 212. 187. + 159. 122. 103. 104. 104. 105. 111. 113. 109. 110. 116. 114. 109. + 112. 121. 120. 120. 122. 127. 131. 132. 128. 124. 131. 132. 125. + 115. 122. 138. 140. 130. 132. 126. 122. 118. 108. 108. 132. 164. + 182. 173. 178. 184. 175. 170. 174. 175. 174. 177. 179. 173. 166. + 167. 179. 191. 187. 186. 185. 187. 190. 191. 191. 190. 194. 196. + 197. 195. 192. 189. 190. 192. 191. 195. 199. 201. 202. 204. 207. + 209. 203. 202. 201. 201. 201. 202. 202. 203. 207. 206. 204. 203. + 204. 205. 206. 206. 212. 226. 228. 206. 153. 74. 77. 113. 126. 137. + 147. 151. 152. 154. 155. 153. 155. 156. 154. 150. 145. 134. 115. 97. + 66. 49. 43. 47. 37. 28. 52. 90. 186. 203. 226. 200. 159. 186. 225. + 213. 222. 221. 221. 222. 223. 225. 230. 236. 180. 48. 38. 46. 45. + 44. 55. 56. 54. 55. 56. 55. 53. 50. 48. 47. 54. 50. 47. 48. 52. 56. + 55. 53. 49. 49. 61. 91. 129. 152. 154. 146. 137. 141. 147. 154. 159. + 162. 163. 162. 160. 160. 159. 159. 159. 158. 158. 158. 90. 90. 90. + 90. 91. 92. 93. 94. 94. 91. 88. 88. 94. 108. 125. 137. 149. 154. + 161. 165. 166. 166. 166. 166. 164. 164. 160. 151. 142. 131. 115. + 100. 80. 69. 70. 77. 76. 82. 92. 92. 98. 98. 99. 100. 100. 100. 100. + 99. 100. 100. 100. 101. 103. 105. 107. 108. 111. 110. 114. 107. 107. + 103. 157. 215. 180. 149. 118. 104. 100. 100. 104. 109. 104. 109. + 115. 117. 115. 113. 113. 114. 116. 119. 124. 130. 132. 131. 126. + 122. 123. 114. 115. 128. 137. 135. 131. 132. 119. 122. 116. 107. + 115. 141. 162. 167. 187. 175. 178. 181. 165. 156. 166. 177. 175. + 174. 175. 179. 179. 176. 175. 176. 191. 189. 187. 188. 190. 191. + 190. 187. 195. 197. 198. 194. 188. 185. 187. 191. 195. 199. 203. + 204. 202. 201. 202. 204. 201. 200. 200. 200. 200. 201. 201. 202. + 210. 207. 205. 205. 206. 207. 208. 207. 210. 224. 225. 213. 200. + 114. 70. 107. 127. 138. 149. 153. 155. 157. 158. 155. 157. 157. 155. + 150. 143. 132. 112. 94. 63. 46. 34. 31. 29. 53. 121. 192. 214. 213. + 180. 166. 198. 213. 211. 226. 213. 216. 218. 218. 219. 223. 229. + 234. 209. 60. 35. 44. 52. 48. 50. 50. 53. 54. 55. 53. 50. 48. 48. + 48. 50. 48. 47. 49. 53. 55. 54. 51. 45. 58. 83. 117. 145. 156. 151. + 142. 135. 144. 155. 160. 159. 158. 158. 160. 159. 159. 159. 159. + 158. 158. 158. 157. 91. 91. 91. 91. 92. 93. 95. 95. 96. 93. 90. 89. + 95. 109. 125. 137. 149. 154. 161. 165. 167. 166. 166. 166. 165. 165. + 161. 152. 143. 132. 115. 100. 81. 70. 72. 78. 77. 83. 94. 95. 97. + 98. 99. 100. 101. 101. 101. 100. 101. 101. 101. 101. 103. 105. 108. + 109. 109. 115. 114. 112. 108. 106. 187. 208. 178. 139. 107. 97. 94. + 96. 102. 103. 100. 112. 117. 111. 109. 114. 116. 113. 119. 123. 128. + 130. 129. 125. 122. 120. 119. 118. 124. 133. 135. 128. 125. 128. + 118. 114. 107. 114. 144. 175. 179. 165. 177. 170. 172. 172. 161. + 162. 171. 172. 176. 173. 175. 183. 186. 181. 175. 175. 191. 193. + 193. 192. 189. 188. 189. 190. 191. 191. 190. 188. 188. 189. 192. + 194. 196. 199. 202. 200. 196. 195. 198. 202. 200. 200. 200. 200. + 200. 202. 203. 203. 210. 207. 204. 204. 207. 208. 208. 207. 207. + 216. 216. 217. 216. 173. 87. 102. 125. 137. 149. 154. 156. 158. 158. + 156. 157. 157. 154. 148. 140. 128. 107. 89. 57. 41. 27. 37. 76. 135. + 194. 231. 196. 166. 172. 203. 216. 222. 219. 203. 210. 216. 216. + 210. 210. 219. 226. 227. 216. 79. 45. 38. 48. 49. 49. 47. 52. 53. + 54. 51. 48. 47. 48. 50. 45. 46. 48. 51. 53. 53. 52. 50. 47. 72. 109. + 139. 152. 152. 145. 139. 142. 149. 158. 160. 158. 156. 157. 159. + 159. 159. 159. 158. 158. 158. 157. 157. 92. 91. 91. 92. 93. 94. 96. + 96. 98. 95. 91. 90. 96. 109. 126. 137. 149. 154. 161. 165. 167. 167. + 167. 167. 166. 166. 161. 152. 143. 132. 115. 100. 82. 71. 73. 79. + 77. 84. 95. 97. 96. 97. 98. 100. 100. 101. 101. 101. 102. 101. 101. + 102. 103. 106. 108. 110. 107. 118. 114. 115. 108. 109. 206. 201. + 184. 137. 102. 94. 93. 99. 106. 103. 104. 116. 116. 101. 98. 112. + 121. 118. 126. 129. 132. 129. 124. 119. 117. 117. 119. 138. 142. + 126. 117. 125. 128. 119. 113. 107. 116. 143. 166. 173. 177. 184. + 171. 165. 163. 161. 165. 180. 181. 161. 175. 176. 180. 184. 180. + 174. 178. 187. 185. 190. 194. 190. 183. 180. 183. 188. 186. 183. + 180. 183. 190. 197. 200. 200. 193. 196. 197. 195. 191. 192. 198. + 204. 201. 200. 200. 201. 202. 203. 204. 205. 208. 204. 201. 202. + 205. 207. 207. 205. 203. 206. 206. 221. 213. 220. 111. 101. 122. + 135. 147. 152. 154. 156. 156. 154. 156. 156. 153. 146. 138. 125. + 104. 85. 45. 38. 39. 78. 156. 219. 217. 182. 164. 179. 198. 216. + 223. 212. 206. 215. 209. 214. 209. 198. 201. 218. 231. 232. 218. 98. + 59. 32. 38. 47. 50. 49. 52. 53. 53. 50. 46. 46. 48. 52. 41. 44. 49. + 52. 53. 52. 50. 49. 59. 91. 132. 157. 160. 151. 144. 142. 150. 154. + 158. 159. 157. 156. 157. 158. 159. 159. 159. 158. 158. 157. 157. + 157. 94. 95. 95. 96. 97. 98. 99. 99. 100. 97. 94. 94. 100. 113. 128. + 139. 148. 154. 162. 168. 170. 169. 167. 167. 166. 167. 164. 156. + 147. 135. 117. 101. 84. 77. 73. 77. 84. 88. 92. 96. 97. 98. 98. 99. + 100. 101. 102. 102. 97. 99. 102. 105. 107. 108. 108. 108. 116. 108. + 116. 102. 100. 126. 212. 198. 177. 141. 108. 99. 103. 104. 106. 110. + 111. 101. 95. 101. 111. 116. 117. 118. 127. 122. 121. 122. 120. 115. + 117. 123. 133. 134. 130. 127. 130. 133. 126. 115. 102. 132. 155. + 158. 163. 178. 181. 171. 170. 158. 156. 168. 175. 172. 170. 174. + 182. 185. 178. 168. 173. 189. 192. 183. 183. 185. 188. 189. 189. + 187. 186. 185. 167. 173. 182. 190. 195. 198. 199. 199. 197. 189. + 194. 207. 206. 191. 186. 194. 204. 201. 199. 201. 205. 206. 204. + 202. 195. 193. 195. 201. 203. 202. 203. 206. 202. 209. 208. 205. + 214. 215. 178. 132. 120. 132. 145. 151. 151. 152. 154. 155. 167. + 154. 144. 141. 136. 119. 97. 82. 46. 67. 118. 183. 221. 213. 183. + 162. 194. 203. 209. 211. 213. 216. 213. 206. 198. 199. 202. 206. + 212. 219. 224. 227. 218. 98. 39. 37. 57. 46. 57. 58. 53. 48. 43. 42. + 45. 46. 46. 44. 46. 49. 51. 51. 47. 43. 42. 44. 68. 117. 152. 157. + 152. 144. 142. 149. 161. 161. 160. 160. 159. 158. 157. 157. 157. + 157. 157. 156. 156. 155. 155. 155. 95. 96. 96. 97. 98. 99. 100. 100. + 99. 97. 94. 94. 100. 112. 128. 139. 148. 154. 162. 167. 169. 168. + 167. 166. 166. 167. 163. 156. 147. 135. 117. 102. 85. 78. 74. 79. + 85. 89. 93. 97. 98. 99. 99. 100. 101. 102. 102. 103. 99. 100. 103. + 105. 108. 109. 109. 109. 115. 113. 115. 105. 100. 142. 216. 200. + 167. 136. 106. 98. 100. 101. 103. 108. 96. 97. 105. 116. 122. 123. + 123. 126. 124. 121. 120. 122. 121. 119. 122. 129. 131. 130. 134. + 138. 132. 118. 110. 109. 132. 140. 157. 171. 171. 161. 157. 160. + 158. 177. 180. 159. 152. 169. 183. 183. 176. 182. 182. 175. 175. + 183. 188. 187. 181. 180. 181. 186. 189. 186. 175. 165. 179. 183. + 187. 187. 185. 187. 194. 201. 208. 196. 190. 193. 194. 192. 197. + 206. 198. 200. 200. 197. 193. 190. 190. 192. 198. 196. 198. 202. + 204. 201. 201. 204. 204. 207. 204. 202. 213. 223. 212. 190. 153. + 141. 137. 146. 153. 153. 154. 159. 151. 150. 151. 150. 136. 108. 80. + 64. 106. 153. 200. 210. 190. 177. 188. 205. 207. 212. 214. 211. 209. + 210. 206. 199. 200. 201. 204. 208. 213. 219. 224. 227. 219. 88. 44. + 40. 51. 45. 53. 59. 54. 51. 47. 45. 45. 46. 47. 47. 49. 51. 54. 53. + 44. 37. 43. 55. 92. 130. 154. 152. 148. 144. 145. 154. 161. 160. + 160. 159. 158. 157. 157. 156. 157. 157. 156. 156. 156. 155. 155. + 155. 97. 97. 98. 99. 99. 100. 100. 101. 98. 96. 94. 94. 100. 112. + 127. 138. 147. 153. 161. 166. 168. 167. 167. 167. 165. 166. 164. + 156. 148. 137. 119. 103. 86. 79. 76. 81. 87. 91. 94. 98. 100. 100. + 100. 101. 102. 103. 103. 103. 100. 101. 103. 106. 108. 109. 110. + 110. 112. 120. 111. 108. 98. 165. 217. 198. 152. 128. 105. 97. 96. + 96. 100. 106. 98. 104. 114. 121. 118. 112. 112. 118. 116. 115. 117. + 120. 121. 121. 124. 130. 130. 125. 129. 137. 126. 106. 106. 121. + 156. 154. 159. 166. 163. 152. 149. 153. 171. 166. 163. 164. 165. + 169. 177. 186. 174. 181. 186. 183. 177. 175. 181. 187. 181. 180. + 180. 180. 179. 175. 169. 164. 182. 187. 191. 188. 182. 182. 189. + 198. 199. 196. 193. 194. 197. 199. 198. 196. 190. 202. 207. 192. + 170. 164. 180. 200. 201. 199. 200. 204. 204. 200. 200. 203. 205. + 204. 200. 197. 203. 213. 218. 218. 203. 167. 141. 145. 154. 152. + 149. 152. 148. 152. 152. 138. 114. 101. 111. 129. 185. 211. 221. + 200. 177. 180. 200. 215. 215. 217. 214. 208. 205. 204. 201. 197. + 203. 204. 206. 210. 215. 219. 223. 226. 220. 71. 48. 44. 45. 46. 48. + 57. 55. 54. 52. 49. 46. 46. 47. 50. 52. 52. 55. 52. 38. 30. 49. 76. + 123. 147. 154. 146. 144. 145. 149. 160. 160. 159. 159. 158. 157. + 156. 156. 155. 157. 156. 156. 156. 155. 155. 155. 155. 99. 99. 99. + 100. 100. 101. 101. 101. 98. 96. 94. 94. 100. 112. 127. 137. 147. + 152. 160. 165. 167. 167. 167. 167. 166. 167. 164. 157. 149. 138. + 120. 104. 86. 79. 76. 81. 88. 91. 94. 98. 101. 101. 101. 102. 102. + 103. 103. 103. 99. 100. 102. 104. 106. 108. 109. 110. 109. 125. 106. + 107. 98. 186. 212. 189. 139. 123. 107. 99. 95. 94. 99. 105. 111. + 111. 113. 112. 106. 102. 107. 116. 112. 115. 120. 124. 125. 125. + 125. 127. 128. 121. 117. 118. 113. 110. 126. 148. 157. 163. 159. + 146. 145. 156. 160. 153. 164. 152. 155. 173. 181. 172. 169. 177. + 178. 180. 184. 184. 178. 171. 175. 184. 182. 185. 184. 174. 164. + 163. 175. 187. 175. 182. 189. 191. 188. 186. 188. 190. 190. 195. + 196. 195. 199. 204. 199. 187. 201. 199. 190. 176. 166. 170. 188. + 204. 201. 199. 200. 203. 204. 200. 200. 202. 200. 196. 195. 198. + 199. 199. 204. 209. 225. 191. 157. 147. 154. 157. 152. 147. 156. + 147. 135. 126. 127. 145. 180. 210. 217. 203. 184. 177. 191. 210. + 213. 205. 212. 211. 207. 203. 201. 202. 202. 202. 206. 207. 209. + 213. 216. 220. 223. 224. 214. 54. 48. 45. 42. 51. 45. 51. 54. 55. + 54. 50. 45. 44. 47. 51. 54. 52. 52. 48. 33. 31. 63. 104. 145. 157. + 152. 142. 144. 148. 153. 163. 159. 159. 158. 157. 156. 156. 155. + 155. 156. 156. 156. 155. 155. 155. 154. 154. 100. 100. 100. 100. + 100. 101. 101. 101. 98. 97. 95. 96. 102. 114. 128. 138. 147. 153. + 160. 165. 167. 168. 168. 169. 167. 168. 165. 158. 150. 138. 120. + 105. 84. 78. 75. 81. 87. 90. 93. 96. 101. 102. 102. 102. 102. 103. + 103. 103. 98. 99. 100. 102. 104. 106. 108. 109. 107. 123. 101. 103. + 101. 200. 203. 175. 135. 124. 111. 103. 98. 96. 101. 106. 110. 106. + 103. 105. 107. 110. 117. 125. 113. 120. 127. 130. 130. 129. 126. + 124. 122. 119. 112. 106. 111. 129. 149. 162. 153. 158. 154. 143. + 142. 153. 157. 152. 135. 162. 179. 172. 167. 175. 179. 173. 179. + 175. 174. 177. 177. 175. 177. 182. 181. 180. 176. 169. 165. 170. + 183. 195. 178. 179. 182. 185. 188. 189. 187. 185. 191. 195. 192. + 185. 190. 203. 207. 200. 207. 185. 164. 165. 183. 199. 198. 191. + 198. 196. 197. 201. 202. 199. 199. 202. 195. 191. 193. 200. 203. + 200. 201. 205. 210. 200. 176. 151. 149. 160. 159. 146. 149. 136. + 134. 157. 188. 207. 210. 207. 196. 184. 180. 194. 209. 214. 212. + 212. 205. 203. 201. 200. 200. 201. 204. 206. 207. 208. 211. 214. + 218. 220. 222. 223. 195. 43. 45. 45. 45. 57. 46. 46. 52. 53. 52. 48. + 44. 43. 46. 50. 54. 51. 49. 45. 36. 45. 86. 130. 152. 157. 149. 142. + 148. 152. 155. 164. 159. 159. 158. 157. 156. 156. 155. 155. 156. + 156. 155. 155. 155. 154. 154. 154. 100. 100. 100. 100. 100. 100. + 100. 100. 99. 98. 97. 98. 104. 115. 129. 139. 149. 153. 160. 165. + 168. 169. 170. 171. 169. 170. 167. 159. 150. 138. 120. 104. 83. 77. + 75. 81. 88. 90. 92. 95. 101. 101. 101. 101. 102. 102. 102. 102. 98. + 98. 99. 100. 102. 105. 107. 108. 105. 117. 97. 99. 112. 210. 196. + 164. 136. 128. 117. 107. 101. 100. 103. 106. 103. 98. 97. 104. 110. + 112. 114. 116. 111. 118. 125. 125. 124. 123. 120. 116. 116. 120. + 119. 117. 127. 145. 156. 156. 155. 146. 147. 157. 153. 139. 138. + 150. 153. 161. 168. 171. 174. 178. 179. 177. 172. 168. 166. 169. + 177. 182. 182. 180. 173. 168. 164. 169. 178. 185. 183. 179. 188. + 182. 176. 175. 180. 184. 184. 183. 180. 188. 191. 190. 194. 201. + 203. 199. 179. 177. 176. 180. 188. 193. 193. 191. 196. 193. 195. + 199. 199. 196. 196. 199. 199. 195. 193. 195. 197. 196. 196. 198. + 197. 209. 196. 159. 142. 151. 153. 142. 140. 152. 177. 202. 212. + 205. 191. 183. 184. 185. 198. 215. 216. 204. 201. 209. 203. 200. + 199. 201. 201. 200. 202. 205. 207. 208. 211. 215. 218. 221. 222. + 223. 162. 41. 44. 46. 51. 57. 50. 44. 51. 50. 48. 46. 44. 44. 46. + 49. 53. 52. 50. 47. 51. 72. 112. 146. 150. 153. 147. 144. 153. 156. + 156. 163. 160. 159. 159. 158. 157. 156. 156. 155. 155. 155. 155. + 155. 154. 154. 154. 153. 100. 100. 100. 99. 99. 99. 99. 99. 100. 99. + 99. 100. 106. 117. 130. 140. 150. 155. 161. 166. 168. 170. 172. 173. + 172. 172. 168. 160. 150. 138. 119. 103. 84. 78. 77. 83. 89. 92. 94. + 96. 101. 101. 101. 101. 100. 100. 100. 100. 99. 99. 99. 100. 103. + 105. 108. 109. 106. 110. 97. 97. 128. 218. 195. 161. 141. 133. 120. + 109. 104. 104. 105. 106. 104. 99. 99. 104. 107. 106. 104. 106. 112. + 118. 120. 116. 115. 118. 118. 115. 114. 118. 128. 139. 146. 149. + 149. 149. 152. 143. 146. 156. 150. 136. 138. 154. 178. 155. 149. + 171. 186. 178. 170. 173. 164. 167. 167. 167. 174. 184. 181. 172. + 161. 163. 169. 176. 181. 181. 177. 172. 186. 182. 177. 174. 175. + 178. 180. 181. 174. 182. 191. 193. 190. 187. 184. 183. 166. 180. + 193. 192. 182. 177. 184. 194. 195. 193. 193. 196. 196. 192. 191. + 193. 195. 197. 196. 191. 187. 187. 187. 187. 194. 211. 205. 170. + 142. 143. 152. 155. 165. 185. 207. 212. 196. 179. 181. 191. 197. + 199. 205. 210. 210. 204. 199. 197. 203. 200. 201. 205. 205. 201. + 201. 204. 205. 207. 211. 215. 218. 221. 222. 223. 124. 45. 46. 49. + 55. 51. 55. 48. 51. 48. 45. 44. 45. 47. 48. 49. 52. 55. 55. 56. 72. + 102. 134. 151. 147. 150. 146. 147. 157. 159. 157. 164. 161. 160. + 160. 159. 158. 157. 157. 156. 155. 155. 155. 154. 154. 154. 153. + 153. 99. 99. 99. 99. 99. 99. 99. 99. 101. 100. 100. 101. 107. 118. + 131. 140. 151. 155. 161. 166. 169. 171. 173. 175. 173. 173. 169. + 161. 151. 137. 118. 102. 85. 80. 78. 85. 91. 93. 95. 97. 100. 100. + 100. 100. 100. 100. 100. 99. 100. 100. 100. 101. 103. 106. 109. 111. + 106. 105. 97. 97. 139. 223. 197. 162. 144. 136. 122. 110. 105. 106. + 106. 104. 108. 104. 102. 105. 106. 106. 110. 116. 120. 124. 123. + 116. 115. 121. 125. 124. 117. 116. 131. 153. 157. 145. 142. 150. + 143. 149. 148. 139. 135. 143. 155. 163. 157. 168. 172. 168. 170. + 176. 172. 161. 161. 171. 174. 169. 172. 181. 176. 162. 151. 168. + 184. 184. 173. 166. 171. 180. 174. 177. 180. 180. 178. 176. 177. + 178. 189. 187. 184. 177. 168. 163. 169. 179. 190. 185. 180. 181. + 185. 187. 184. 180. 196. 193. 192. 195. 193. 188. 187. 189. 179. + 191. 198. 193. 187. 188. 189. 187. 186. 200. 200. 176. 150. 147. + 166. 184. 205. 200. 197. 196. 193. 191. 193. 198. 206. 213. 212. + 201. 198. 205. 207. 201. 202. 199. 202. 209. 209. 204. 202. 205. + 204. 207. 210. 215. 218. 221. 222. 222. 99. 50. 49. 52. 57. 45. 57. + 52. 52. 48. 44. 44. 47. 50. 50. 49. 52. 58. 60. 64. 87. 123. 146. + 150. 146. 150. 146. 149. 159. 160. 157. 164. 161. 161. 160. 160. + 159. 158. 157. 157. 155. 155. 155. 154. 154. 153. 153. 153. 100. + 100. 100. 99. 99. 98. 98. 98. 100. 101. 100. 100. 104. 114. 129. + 140. 150. 158. 165. 168. 170. 173. 173. 171. 172. 173. 171. 163. + 153. 139. 119. 102. 84. 78. 77. 84. 92. 94. 94. 94. 94. 97. 101. + 102. 101. 99. 99. 99. 96. 97. 98. 100. 102. 104. 105. 106. 104. 101. + 96. 86. 190. 209. 189. 166. 148. 139. 125. 112. 104. 103. 105. 107. + 106. 103. 103. 108. 112. 111. 110. 111. 122. 116. 113. 120. 125. + 124. 120. 119. 114. 129. 144. 151. 153. 152. 143. 133. 147. 148. + 138. 128. 139. 161. 164. 151. 154. 164. 165. 156. 153. 163. 170. + 169. 179. 171. 172. 178. 175. 161. 153. 156. 178. 174. 171. 174. + 179. 181. 178. 173. 176. 175. 173. 173. 175. 178. 182. 185. 193. + 190. 181. 173. 173. 181. 186. 187. 192. 184. 177. 180. 189. 195. + 192. 186. 191. 193. 194. 192. 189. 186. 185. 185. 191. 185. 186. + 194. 193. 184. 182. 188. 180. 189. 194. 187. 175. 177. 195. 214. + 198. 190. 183. 185. 195. 204. 209. 209. 206. 205. 203. 202. 201. + 200. 200. 200. 196. 205. 208. 201. 199. 204. 205. 200. 190. 218. + 215. 204. 225. 228. 214. 219. 72. 55. 43. 47. 55. 55. 52. 51. 53. + 50. 46. 45. 45. 47. 48. 49. 57. 57. 62. 79. 109. 137. 150. 149. 142. + 144. 149. 153. 157. 158. 159. 159. 160. 159. 158. 157. 157. 157. + 157. 158. 155. 155. 155. 155. 155. 155. 155. 155. 100. 100. 99. 99. + 99. 98. 98. 98. 100. 100. 100. 100. 104. 114. 129. 140. 149. 158. + 165. 168. 170. 174. 174. 172. 173. 173. 170. 162. 152. 139. 120. + 103. 85. 77. 74. 80. 88. 92. 93. 95. 95. 97. 101. 102. 101. 99. 99. + 99. 97. 97. 99. 100. 102. 103. 105. 105. 102. 98. 93. 92. 197. 209. + 191. 171. 148. 139. 126. 113. 106. 103. 103. 104. 104. 102. 105. + 111. 114. 113. 114. 117. 126. 119. 116. 122. 128. 125. 119. 115. + 132. 140. 151. 156. 148. 139. 141. 151. 142. 133. 131. 140. 147. + 148. 152. 158. 167. 163. 159. 156. 155. 156. 164. 172. 180. 176. + 173. 170. 160. 152. 163. 182. 178. 175. 172. 172. 175. 177. 176. + 174. 171. 170. 170. 171. 175. 180. 186. 189. 183. 184. 182. 178. + 179. 183. 184. 181. 190. 187. 185. 185. 188. 192. 193. 193. 189. + 189. 189. 186. 183. 182. 183. 184. 190. 185. 184. 185. 179. 172. + 178. 192. 181. 182. 186. 192. 197. 200. 199. 197. 194. 192. 192. + 196. 202. 205. 204. 202. 205. 204. 203. 201. 200. 200. 200. 200. + 201. 205. 207. 204. 203. 203. 200. 195. 200. 213. 212. 207. 221. + 219. 221. 205. 50. 43. 39. 44. 47. 46. 46. 49. 53. 49. 45. 44. 48. + 52. 54. 54. 60. 65. 77. 98. 128. 150. 155. 149. 145. 148. 153. 158. + 161. 162. 161. 161. 160. 159. 158. 157. 157. 157. 157. 158. 155. + 155. 155. 155. 155. 155. 155. 155. 100. 99. 99. 99. 98. 98. 98. 98. + 99. 100. 100. 100. 104. 114. 129. 140. 149. 157. 165. 168. 170. 174. + 175. 173. 174. 174. 169. 161. 151. 139. 120. 105. 85. 76. 71. 76. + 84. 89. 92. 95. 95. 98. 101. 101. 100. 99. 99. 100. 97. 98. 99. 100. + 102. 103. 104. 105. 102. 95. 90. 103. 207. 208. 192. 177. 150. 143. + 132. 122. 116. 113. 111. 109. 104. 103. 107. 112. 113. 111. 112. + 117. 123. 122. 124. 127. 124. 118. 118. 123. 146. 152. 152. 144. + 139. 142. 147. 149. 132. 130. 136. 147. 151. 147. 149. 155. 165. + 153. 151. 161. 165. 160. 164. 175. 177. 170. 165. 162. 157. 157. + 171. 189. 175. 174. 173. 173. 173. 173. 174. 174. 174. 172. 170. + 170. 173. 177. 183. 186. 175. 181. 184. 183. 183. 183. 180. 174. + 184. 187. 190. 189. 186. 186. 191. 196. 187. 185. 183. 179. 176. + 177. 180. 184. 185. 177. 176. 183. 185. 176. 168. 166. 177. 186. + 196. 199. 196. 193. 193. 196. 192. 196. 203. 208. 209. 205. 200. + 195. 203. 202. 201. 200. 199. 199. 199. 200. 204. 203. 205. 207. + 205. 197. 192. 191. 205. 203. 209. 212. 220. 211. 224. 165. 36. 38. + 43. 48. 47. 45. 49. 56. 50. 44. 40. 41. 48. 53. 54. 53. 50. 66. 89. + 117. 142. 156. 152. 141. 147. 151. 156. 161. 163. 163. 162. 160. + 160. 159. 158. 157. 157. 157. 157. 158. 155. 155. 155. 155. 155. + 155. 155. 155. 99. 99. 99. 98. 98. 98. 97. 97. 98. 99. 99. 99. 103. + 114. 129. 140. 149. 157. 165. 168. 171. 175. 176. 174. 174. 174. + 169. 159. 150. 138. 121. 106. 85. 76. 72. 78. 86. 90. 92. 94. 96. + 98. 100. 101. 100. 99. 99. 100. 98. 98. 99. 100. 102. 103. 104. 104. + 103. 96. 89. 113. 217. 204. 191. 178. 150. 144. 136. 129. 126. 122. + 118. 115. 106. 105. 107. 110. 108. 104. 106. 111. 117. 122. 127. + 124. 115. 112. 124. 140. 148. 154. 144. 128. 135. 155. 149. 125. + 128. 145. 153. 148. 150. 159. 155. 140. 144. 141. 148. 165. 176. + 175. 172. 173. 166. 156. 153. 163. 173. 174. 171. 170. 169. 172. + 175. 175. 174. 173. 174. 174. 180. 177. 173. 170. 169. 171. 173. + 175. 176. 181. 184. 182. 180. 180. 178. 173. 177. 183. 188. 189. + 186. 184. 185. 188. 186. 184. 180. 175. 173. 174. 179. 183. 183. + 177. 174. 177. 177. 171. 166. 165. 187. 193. 196. 190. 182. 181. + 189. 198. 196. 202. 209. 211. 208. 202. 197. 195. 201. 201. 200. + 199. 199. 199. 200. 200. 202. 201. 204. 207. 198. 183. 181. 188. + 203. 196. 208. 214. 220. 214. 218. 108. 35. 40. 47. 50. 48. 49. 54. + 60. 50. 45. 42. 44. 51. 55. 53. 49. 38. 66. 104. 133. 149. 153. 146. + 137. 148. 151. 156. 161. 163. 162. 160. 158. 160. 159. 158. 157. + 157. 157. 157. 158. 156. 156. 156. 156. 156. 156. 156. 156. 99. 99. + 98. 98. 98. 97. 97. 97. 97. 98. 98. 99. 103. 114. 129. 140. 150. + 158. 166. 168. 171. 175. 176. 173. 173. 173. 168. 159. 150. 139. + 122. 107. 83. 77. 75. 82. 90. 93. 93. 93. 96. 98. 100. 100. 99. 98. + 99. 101. 98. 99. 99. 100. 102. 103. 103. 104. 104. 99. 89. 121. 222. + 199. 189. 175. 151. 145. 137. 131. 128. 123. 116. 110. 108. 105. + 105. 107. 106. 104. 106. 111. 121. 115. 111. 113. 118. 125. 136. + 147. 147. 146. 140. 135. 140. 144. 134. 117. 139. 152. 156. 150. + 153. 161. 151. 132. 138. 145. 152. 159. 172. 181. 176. 165. 154. + 152. 158. 171. 182. 180. 169. 160. 163. 168. 174. 178. 178. 176. + 174. 173. 175. 173. 170. 168. 168. 169. 171. 172. 175. 179. 180. + 176. 175. 179. 182. 183. 177. 180. 184. 188. 189. 187. 181. 177. + 184. 183. 180. 177. 174. 174. 177. 180. 186. 181. 173. 162. 155. + 161. 180. 200. 200. 189. 177. 177. 186. 195. 197. 196. 201. 205. + 208. 206. 201. 198. 198. 200. 200. 200. 199. 199. 199. 200. 201. + 201. 204. 204. 206. 201. 183. 165. 167. 180. 202. 196. 205. 205. + 212. 221. 197. 67. 38. 41. 43. 44. 45. 48. 52. 54. 53. 50. 48. 50. + 55. 56. 52. 48. 42. 80. 124. 149. 153. 150. 147. 146. 151. 154. 158. + 162. 163. 162. 160. 158. 160. 159. 158. 157. 157. 157. 157. 158. + 156. 156. 156. 156. 156. 156. 156. 156. 98. 98. 98. 98. 97. 97. 97. + 96. 96. 97. 97. 98. 103. 114. 129. 140. 152. 160. 167. 169. 171. + 175. 175. 172. 172. 172. 168. 160. 151. 139. 122. 106. 84. 78. 77. + 85. 93. 95. 94. 94. 97. 98. 100. 99. 98. 98. 100. 101. 99. 99. 100. + 101. 101. 102. 103. 103. 102. 103. 89. 123. 222. 195. 188. 170. 161. + 153. 144. 138. 134. 127. 118. 110. 110. 104. 101. 104. 108. 110. + 114. 119. 127. 107. 95. 107. 131. 146. 145. 139. 147. 139. 144. 153. + 141. 118. 117. 136. 154. 146. 146. 154. 157. 149. 141. 139. 150. + 156. 154. 149. 156. 169. 167. 155. 153. 162. 174. 178. 174. 169. + 169. 171. 162. 166. 171. 176. 178. 176. 172. 169. 162. 163. 164. + 166. 168. 170. 172. 173. 169. 173. 174. 171. 171. 179. 187. 190. + 182. 181. 182. 186. 190. 188. 180. 172. 178. 180. 181. 180. 176. + 173. 172. 172. 185. 171. 158. 160. 174. 188. 194. 195. 185. 184. + 185. 189. 195. 202. 206. 208. 202. 203. 202. 199. 195. 195. 199. + 203. 200. 199. 199. 199. 200. 201. 202. 203. 208. 208. 204. 188. + 166. 153. 160. 173. 193. 189. 193. 194. 202. 219. 157. 51. 44. 46. + 45. 44. 46. 51. 51. 48. 47. 46. 46. 47. 50. 51. 52. 51. 62. 99. 139. + 154. 150. 145. 148. 153. 157. 159. 161. 163. 164. 163. 162. 161. + 160. 159. 158. 157. 157. 157. 157. 158. 157. 157. 157. 157. 157. + 157. 157. 157. 98. 98. 98. 97. 97. 97. 96. 96. 96. 96. 97. 98. 103. + 114. 129. 140. 154. 162. 168. 170. 171. 174. 174. 171. 170. 171. + 169. 162. 153. 140. 122. 105. 86. 79. 76. 83. 91. 94. 95. 96. 97. + 99. 100. 99. 98. 98. 100. 102. 99. 99. 100. 101. 101. 102. 103. 103. + 98. 105. 88. 122. 220. 192. 190. 167. 166. 158. 149. 144. 141. 136. + 127. 118. 114. 103. 95. 99. 106. 112. 116. 120. 119. 107. 105. 122. + 143. 150. 142. 133. 141. 142. 146. 143. 127. 116. 128. 150. 152. + 146. 145. 150. 150. 144. 145. 150. 154. 152. 149. 147. 150. 154. + 154. 151. 163. 172. 178. 174. 165. 162. 168. 174. 167. 166. 166. + 169. 173. 172. 168. 164. 160. 161. 164. 166. 167. 167. 166. 165. + 162. 169. 173. 171. 170. 176. 182. 184. 186. 183. 180. 180. 182. + 182. 177. 172. 170. 175. 180. 181. 177. 171. 164. 161. 170. 165. + 166. 180. 199. 205. 193. 176. 178. 192. 204. 205. 198. 195. 202. + 212. 196. 196. 196. 195. 195. 196. 199. 201. 200. 200. 200. 200. + 201. 203. 204. 205. 208. 205. 193. 172. 156. 156. 166. 174. 164. + 165. 175. 193. 198. 205. 99. 44. 45. 51. 53. 50. 50. 53. 52. 47. 42. + 42. 42. 42. 44. 51. 60. 66. 91. 119. 146. 152. 144. 141. 148. 155. + 160. 161. 161. 162. 162. 162. 162. 161. 160. 159. 158. 157. 157. + 157. 157. 158. 157. 157. 157. 157. 157. 157. 157. 157. 98. 98. 98. + 97. 97. 96. 96. 96. 95. 96. 97. 98. 102. 114. 129. 140. 155. 163. + 169. 170. 171. 173. 173. 170. 169. 171. 169. 163. 154. 141. 121. + 105. 88. 80. 75. 80. 88. 93. 95. 98. 98. 99. 99. 99. 98. 98. 100. + 102. 99. 100. 100. 101. 101. 102. 102. 103. 94. 105. 87. 120. 219. + 192. 192. 165. 160. 153. 145. 142. 142. 140. 132. 125. 118. 103. 92. + 94. 103. 109. 113. 115. 102. 112. 129. 143. 146. 139. 135. 137. 132. + 149. 143. 114. 109. 136. 153. 149. 141. 154. 155. 141. 137. 151. + 159. 155. 144. 138. 141. 152. 156. 148. 147. 152. 175. 174. 170. + 166. 165. 166. 165. 163. 172. 167. 163. 163. 167. 168. 165. 160. + 167. 168. 168. 167. 164. 159. 155. 151. 160. 169. 176. 174. 171. + 171. 172. 172. 186. 183. 178. 174. 173. 173. 173. 173. 164. 171. + 179. 182. 177. 168. 158. 152. 152. 176. 199. 200. 186. 178. 184. + 194. 201. 201. 202. 203. 203. 200. 195. 191. 189. 190. 193. 195. + 197. 198. 197. 197. 200. 200. 200. 201. 202. 203. 205. 206. 204. + 199. 181. 159. 153. 166. 178. 180. 133. 140. 162. 199. 200. 192. 52. + 37. 39. 50. 56. 54. 51. 51. 49. 44. 46. 46. 46. 45. 48. 59. 75. 88. + 117. 136. 151. 151. 144. 144. 151. 158. 160. 159. 159. 158. 158. + 158. 159. 160. 160. 159. 158. 157. 157. 157. 157. 158. 157. 157. + 157. 157. 157. 157. 157. 157. 97. 97. 96. 95. 94. 94. 93. 92. 93. + 94. 95. 97. 103. 115. 131. 142. 155. 160. 166. 170. 172. 171. 171. + 171. 172. 171. 166. 159. 152. 142. 123. 107. 87. 78. 74. 79. 87. 92. + 94. 97. 97. 98. 99. 99. 97. 97. 98. 99. 98. 98. 100. 101. 101. 101. + 101. 101. 95. 102. 80. 138. 213. 191. 174. 173. 163. 162. 163. 144. + 139. 143. 145. 124. 107. 99. 92. 94. 105. 113. 109. 101. 104. 127. + 146. 146. 135. 130. 135. 142. 143. 128. 110. 117. 137. 140. 139. + 147. 151. 146. 141. 141. 144. 147. 147. 145. 145. 161. 168. 148. + 136. 157. 170. 156. 161. 158. 160. 167. 170. 168. 167. 169. 170. + 167. 169. 164. 155. 161. 173. 171. 161. 163. 168. 161. 151. 159. + 171. 168. 168. 162. 171. 175. 176. 174. 167. 173. 179. 184. 181. + 169. 165. 171. 175. 174. 166. 171. 175. 173. 167. 162. 162. 164. + 196. 192. 185. 178. 177. 181. 190. 196. 209. 207. 203. 200. 196. + 194. 193. 193. 191. 192. 194. 196. 197. 198. 198. 198. 199. 203. + 203. 199. 200. 206. 208. 205. 205. 194. 168. 147. 158. 179. 170. + 143. 136. 163. 178. 187. 221. 126. 42. 39. 33. 43. 54. 58. 54. 48. + 46. 46. 48. 53. 52. 45. 45. 61. 85. 101. 139. 148. 151. 145. 142. + 148. 157. 161. 162. 162. 161. 161. 160. 159. 158. 158. 159. 159. + 159. 158. 158. 157. 157. 157. 158. 158. 158. 157. 157. 156. 156. + 156. 97. 97. 96. 96. 95. 94. 93. 93. 92. 94. 95. 97. 102. 114. 130. + 141. 155. 160. 166. 170. 172. 171. 171. 171. 172. 171. 166. 160. + 153. 142. 123. 107. 88. 80. 75. 81. 88. 92. 95. 97. 98. 99. 101. + 100. 98. 98. 99. 100. 98. 99. 100. 100. 101. 101. 101. 100. 94. 95. + 80. 146. 208. 189. 177. 171. 159. 161. 149. 151. 127. 143. 133. 123. + 110. 104. 102. 105. 105. 103. 106. 113. 134. 142. 145. 138. 130. + 131. 137. 140. 126. 126. 121. 127. 141. 142. 139. 145. 143. 144. + 144. 142. 139. 139. 141. 144. 161. 149. 147. 148. 144. 150. 165. + 170. 164. 159. 155. 160. 169. 172. 166. 158. 158. 153. 160. 167. + 161. 162. 167. 165. 169. 151. 150. 161. 165. 166. 164. 155. 170. + 166. 172. 175. 174. 168. 160. 163. 165. 163. 168. 175. 176. 169. + 166. 169. 158. 164. 167. 163. 158. 162. 177. 191. 178. 180. 183. + 186. 189. 194. 199. 204. 201. 200. 198. 196. 194. 194. 194. 194. + 193. 194. 195. 197. 198. 199. 199. 199. 200. 201. 203. 204. 204. + 203. 207. 211. 209. 171. 149. 166. 184. 173. 148. 132. 160. 163. + 182. 195. 207. 94. 39. 36. 39. 43. 49. 52. 52. 48. 44. 41. 51. 47. + 48. 51. 54. 65. 91. 117. 145. 151. 151. 146. 144. 150. 157. 159. + 161. 161. 161. 160. 159. 158. 158. 157. 159. 159. 158. 158. 158. + 157. 157. 157. 158. 158. 157. 157. 157. 156. 156. 156. 97. 97. 96. + 96. 95. 94. 94. 94. 92. 94. 95. 97. 103. 114. 129. 140. 154. 159. + 166. 170. 172. 172. 171. 172. 172. 171. 167. 160. 153. 142. 123. + 106. 90. 81. 77. 82. 89. 93. 95. 97. 99. 100. 101. 101. 99. 98. 100. + 101. 98. 99. 99. 100. 101. 100. 100. 100. 94. 88. 84. 161. 204. 189. + 185. 173. 170. 152. 163. 140. 149. 128. 142. 126. 115. 112. 112. + 112. 104. 98. 109. 127. 150. 148. 141. 133. 131. 134. 134. 130. 110. + 127. 135. 138. 146. 146. 140. 142. 138. 140. 140. 137. 134. 137. + 144. 151. 155. 138. 141. 155. 155. 152. 155. 155. 152. 156. 156. + 154. 159. 166. 160. 149. 163. 157. 166. 177. 173. 167. 161. 151. + 150. 139. 152. 173. 172. 164. 171. 179. 156. 157. 161. 169. 172. + 169. 169. 170. 168. 164. 163. 166. 168. 167. 164. 163. 161. 153. + 149. 156. 172. 185. 188. 186. 171. 178. 187. 195. 199. 200. 201. + 201. 191. 191. 191. 191. 192. 193. 195. 195. 195. 196. 197. 199. + 200. 201. 201. 201. 202. 201. 203. 208. 208. 206. 207. 212. 188. + 159. 151. 171. 174. 152. 146. 160. 166. 158. 183. 207. 176. 56. 40. + 40. 47. 47. 47. 49. 51. 50. 46. 42. 53. 44. 44. 56. 63. 72. 103. + 137. 151. 152. 150. 146. 147. 153. 158. 158. 160. 160. 159. 159. + 158. 157. 156. 156. 159. 158. 158. 158. 157. 157. 157. 157. 158. + 157. 157. 157. 156. 156. 156. 156. 97. 97. 97. 96. 96. 95. 95. 94. + 94. 96. 97. 99. 105. 116. 130. 141. 154. 159. 166. 170. 172. 172. + 172. 172. 171. 171. 168. 161. 154. 143. 123. 106. 90. 81. 76. 81. + 88. 92. 93. 95. 98. 99. 100. 100. 98. 98. 99. 100. 98. 99. 99. 100. + 100. 100. 99. 99. 97. 83. 88. 179. 204. 193. 194. 179. 174. 167. + 147. 170. 135. 149. 133. 139. 121. 120. 113. 104. 101. 109. 123. + 134. 137. 138. 137. 135. 136. 135. 126. 116. 112. 134. 142. 141. + 148. 149. 142. 140. 139. 134. 130. 130. 136. 145. 153. 157. 137. + 140. 150. 156. 157. 164. 162. 146. 145. 161. 168. 158. 152. 154. + 151. 141. 154. 154. 159. 159. 157. 165. 162. 143. 162. 157. 168. + 177. 163. 153. 161. 169. 168. 170. 162. 165. 164. 158. 164. 161. + 161. 167. 165. 156. 158. 167. 164. 152. 161. 157. 158. 172. 189. + 194. 183. 170. 185. 190. 196. 199. 198. 194. 190. 188. 187. 187. + 188. 190. 191. 193. 195. 196. 197. 198. 200. 201. 202. 202. 202. + 202. 202. 205. 205. 204. 210. 215. 210. 200. 155. 160. 165. 162. + 154. 150. 155. 165. 144. 157. 189. 218. 129. 34. 44. 47. 53. 52. 51. + 51. 52. 53. 53. 53. 54. 48. 46. 54. 66. 86. 120. 150. 153. 150. 146. + 146. 150. 156. 159. 159. 159. 159. 158. 157. 157. 156. 155. 155. + 158. 158. 158. 157. 157. 157. 156. 156. 157. 157. 157. 156. 156. + 156. 155. 155. 97. 97. 97. 96. 96. 96. 96. 95. 96. 98. 101. 103. + 108. 118. 132. 142. 153. 158. 165. 170. 172. 172. 172. 173. 171. + 171. 168. 162. 155. 144. 124. 106. 87. 79. 74. 79. 86. 90. 92. 94. + 96. 97. 98. 98. 96. 96. 97. 98. 98. 99. 99. 100. 100. 99. 98. 98. + 97. 79. 87. 189. 204. 196. 197. 185. 182. 154. 168. 148. 162. 131. + 149. 140. 128. 124. 107. 90. 101. 128. 139. 132. 122. 130. 136. 136. + 133. 129. 121. 113. 128. 143. 143. 138. 145. 148. 141. 138. 136. + 128. 124. 132. 146. 155. 151. 143. 136. 143. 156. 159. 154. 161. + 165. 156. 144. 158. 162. 155. 152. 155. 147. 132. 128. 134. 130. + 112. 115. 150. 169. 154. 173. 161. 157. 158. 158. 166. 166. 153. + 165. 172. 157. 161. 161. 157. 172. 166. 152. 156. 160. 162. 161. + 158. 153. 148. 160. 175. 188. 189. 179. 173. 179. 187. 199. 200. + 199. 195. 190. 186. 183. 183. 188. 189. 190. 192. 193. 195. 195. + 196. 199. 200. 201. 202. 203. 203. 203. 203. 202. 210. 207. 199. + 209. 223. 209. 179. 153. 161. 162. 155. 150. 147. 134. 119. 127. + 175. 205. 215. 79. 32. 41. 47. 51. 53. 55. 53. 50. 52. 58. 64. 54. + 56. 52. 50. 68. 104. 137. 152. 150. 145. 143. 146. 153. 158. 160. + 160. 159. 158. 158. 157. 156. 155. 155. 155. 158. 158. 157. 157. + 157. 156. 156. 156. 157. 157. 156. 156. 156. 155. 155. 155. 97. 97. + 97. 97. 97. 96. 96. 96. 98. 100. 103. 105. 110. 120. 133. 143. 153. + 158. 165. 170. 172. 172. 173. 173. 171. 172. 169. 163. 156. 144. + 124. 106. 85. 76. 72. 78. 86. 90. 92. 95. 95. 96. 98. 97. 95. 95. + 96. 97. 98. 99. 99. 99. 99. 98. 97. 97. 94. 77. 80. 190. 205. 198. + 194. 188. 180. 172. 154. 174. 144. 157. 145. 151. 137. 126. 104. 90. + 107. 137. 143. 129. 124. 133. 137. 130. 122. 120. 123. 125. 142. + 147. 139. 134. 141. 142. 135. 135. 129. 127. 129. 140. 151. 151. + 139. 126. 142. 141. 158. 170. 153. 133. 130. 130. 126. 124. 122. + 127. 144. 155. 145. 127. 135. 140. 129. 99. 94. 136. 168. 163. 164. + 161. 162. 158. 153. 163. 168. 156. 155. 169. 153. 161. 160. 149. + 164. 149. 173. 159. 157. 163. 154. 138. 147. 171. 181. 185. 186. + 180. 173. 176. 190. 203. 198. 198. 195. 191. 187. 186. 188. 190. + 191. 192. 194. 195. 196. 197. 197. 197. 200. 201. 202. 203. 203. + 203. 203. 203. 203. 210. 207. 200. 209. 219. 197. 162. 170. 158. + 148. 138. 120. 101. 100. 112. 145. 203. 218. 179. 45. 39. 34. 41. + 47. 51. 53. 50. 46. 48. 57. 66. 54. 59. 55. 55. 80. 123. 148. 150. + 147. 143. 143. 149. 156. 158. 159. 161. 159. 159. 158. 157. 157. + 156. 155. 155. 157. 157. 157. 157. 156. 156. 156. 155. 156. 156. + 156. 156. 155. 155. 155. 154. 97. 97. 97. 97. 97. 97. 97. 97. 98. + 100. 103. 106. 110. 120. 132. 142. 152. 158. 165. 170. 172. 173. + 173. 174. 171. 172. 169. 164. 157. 145. 124. 106. 84. 76. 72. 78. + 87. 92. 95. 97. 96. 97. 98. 98. 96. 95. 97. 98. 99. 99. 99. 99. 99. + 98. 97. 96. 93. 79. 74. 189. 208. 202. 191. 194. 183. 166. 172. 157. + 162. 149. 162. 151. 146. 127. 108. 107. 119. 130. 132. 129. 128. + 134. 133. 122. 114. 118. 130. 138. 143. 144. 137. 135. 139. 132. + 125. 131. 127. 134. 141. 144. 141. 137. 135. 135. 146. 145. 154. + 152. 130. 115. 114. 112. 115. 106. 100. 105. 118. 127. 125. 119. + 156. 159. 157. 134. 113. 124. 142. 143. 156. 158. 169. 167. 149. + 140. 144. 144. 151. 172. 155. 163. 151. 122. 123. 92. 146. 154. 158. + 151. 141. 145. 167. 188. 188. 178. 170. 175. 189. 200. 201. 197. + 193. 193. 193. 192. 190. 190. 192. 194. 192. 194. 196. 197. 199. + 199. 199. 198. 201. 201. 202. 203. 203. 203. 203. 202. 206. 206. + 207. 211. 212. 202. 178. 156. 157. 135. 117. 106. 85. 74. 104. 148. + 181. 215. 211. 113. 29. 45. 33. 41. 49. 49. 48. 46. 45. 48. 55. 60. + 54. 54. 55. 69. 102. 137. 152. 150. 147. 144. 147. 155. 159. 158. + 158. 161. 160. 159. 159. 158. 157. 156. 156. 156. 157. 157. 157. + 156. 156. 156. 155. 155. 156. 156. 156. 155. 155. 155. 154. 154. 97. + 97. 97. 97. 97. 97. 97. 97. 97. 100. 103. 105. 110. 119. 131. 141. + 152. 157. 165. 170. 172. 173. 173. 174. 171. 172. 170. 164. 157. + 145. 124. 105. 84. 76. 72. 79. 88. 93. 97. 99. 97. 98. 99. 99. 97. + 97. 98. 99. 99. 99. 99. 99. 99. 97. 96. 96. 95. 83. 72. 189. 213. + 207. 191. 199. 174. 167. 160. 160. 147. 154. 155. 148. 153. 127. + 115. 125. 129. 119. 119. 131. 125. 130. 128. 119. 113. 120. 134. + 144. 139. 139. 136. 138. 139. 125. 118. 128. 130. 142. 149. 142. + 127. 125. 141. 159. 155. 157. 142. 107. 92. 120. 146. 140. 130. 124. + 116. 106. 94. 87. 94. 106. 151. 157. 173. 169. 137. 114. 112. 113. + 119. 108. 123. 152. 159. 154. 152. 150. 106. 139. 134. 155. 150. + 119. 117. 81. 62. 123. 158. 144. 143. 176. 193. 180. 166. 170. 179. + 193. 204. 206. 199. 191. 191. 193. 196. 196. 194. 192. 190. 190. + 192. 193. 196. 198. 200. 200. 200. 200. 201. 201. 202. 203. 203. + 203. 202. 202. 208. 200. 206. 221. 215. 186. 163. 157. 124. 99. 79. + 79. 87. 103. 132. 162. 206. 210. 194. 58. 25. 49. 37. 47. 54. 50. + 45. 44. 47. 51. 54. 55. 55. 47. 53. 83. 120. 144. 152. 152. 148. + 147. 151. 160. 162. 157. 156. 160. 160. 160. 159. 159. 158. 157. + 156. 156. 157. 157. 157. 156. 156. 155. 155. 155. 156. 156. 156. + 155. 155. 154. 154. 154. 96. 96. 96. 97. 97. 97. 98. 98. 98. 100. + 103. 105. 110. 119. 133. 142. 154. 161. 169. 173. 173. 173. 174. + 176. 173. 173. 170. 165. 158. 146. 125. 107. 86. 77. 72. 77. 85. 89. + 92. 95. 95. 97. 98. 98. 98. 98. 99. 101. 99. 100. 100. 100. 99. 97. + 95. 94. 85. 70. 90. 175. 209. 201. 206. 187. 186. 180. 172. 162. + 151. 143. 145. 152. 157. 134. 115. 115. 119. 118. 119. 125. 135. + 121. 108. 109. 124. 139. 144. 143. 137. 136. 134. 128. 123. 123. + 127. 132. 134. 138. 131. 145. 127. 136. 134. 152. 146. 140. 131. + 127. 133. 140. 136. 128. 115. 122. 103. 99. 95. 96. 66. 101. 153. + 169. 165. 159. 131. 131. 124. 128. 129. 105. 106. 88. 102. 113. 133. + 137. 113. 102. 89. 59. 74. 68. 88. 99. 31. 83. 140. 163. 188. 188. + 158. 160. 174. 179. 188. 195. 198. 197. 194. 191. 196. 197. 197. + 195. 193. 193. 194. 196. 192. 194. 199. 203. 203. 200. 199. 200. + 199. 197. 203. 205. 200. 205. 208. 198. 205. 209. 213. 209. 188. + 155. 127. 113. 81. 77. 94. 102. 94. 116. 166. 194. 215. 220. 86. 44. + 42. 40. 51. 48. 41. 46. 46. 41. 42. 50. 55. 54. 46. 44. 65. 109. + 145. 154. 150. 148. 142. 150. 159. 162. 161. 159. 160. 162. 159. + 159. 158. 157. 157. 156. 155. 155. 155. 155. 155. 154. 154. 153. + 153. 153. 154. 154. 154. 154. 154. 154. 154. 154. 97. 98. 99. 99. + 99. 99. 98. 98. 101. 103. 106. 108. 112. 122. 136. 145. 154. 161. + 169. 173. 173. 173. 174. 175. 173. 173. 170. 165. 158. 146. 125. + 107. 86. 77. 72. 77. 85. 89. 93. 95. 95. 97. 98. 98. 98. 98. 99. + 101. 97. 98. 99. 100. 100. 98. 97. 96. 95. 76. 90. 162. 215. 203. + 206. 192. 193. 186. 174. 159. 144. 137. 144. 155. 151. 129. 112. + 114. 121. 122. 124. 129. 116. 113. 113. 123. 136. 142. 139. 133. + 139. 137. 132. 126. 123. 124. 127. 131. 138. 137. 126. 138. 130. + 144. 140. 148. 155. 129. 114. 127. 145. 142. 120. 100. 116. 101. 86. + 79. 73. 66. 60. 105. 144. 147. 171. 142. 152. 118. 123. 105. 106. + 97. 89. 76. 105. 89. 71. 65. 69. 73. 74. 51. 58. 41. 46. 49. 34. 65. + 160. 198. 162. 152. 165. 174. 191. 193. 195. 197. 197. 196. 193. + 191. 196. 196. 196. 195. 193. 192. 194. 196. 199. 196. 195. 197. + 200. 201. 203. 204. 200. 203. 210. 205. 192. 197. 210. 211. 217. + 199. 177. 156. 135. 112. 94. 87. 91. 86. 87. 96. 115. 153. 186. 195. + 227. 144. 54. 37. 41. 44. 41. 48. 45. 48. 47. 44. 45. 51. 53. 51. + 44. 50. 77. 119. 147. 151. 147. 146. 145. 152. 160. 163. 161. 159. + 159. 161. 159. 159. 158. 158. 157. 156. 155. 155. 155. 155. 155. + 154. 154. 154. 153. 153. 154. 154. 154. 154. 154. 154. 154. 154. 98. + 99. 101. 102. 102. 101. 99. 97. 102. 104. 106. 109. 113. 123. 137. + 146. 154. 160. 168. 173. 173. 172. 173. 175. 173. 173. 170. 165. + 158. 146. 125. 107. 86. 77. 72. 77. 85. 90. 93. 96. 95. 97. 98. 98. + 98. 98. 99. 101. 95. 96. 98. 99. 100. 99. 98. 97. 102. 80. 87. 139. + 221. 203. 202. 196. 198. 192. 180. 160. 138. 126. 132. 145. 138. + 119. 105. 109. 117. 120. 121. 123. 103. 109. 119. 133. 142. 143. + 136. 129. 136. 132. 127. 125. 126. 129. 131. 133. 138. 135. 124. + 132. 135. 151. 143. 139. 120. 116. 126. 146. 144. 120. 102. 101. + 104. 84. 100. 106. 105. 83. 87. 122. 119. 137. 127. 144. 109. 113. + 76. 70. 66. 44. 89. 116. 93. 46. 68. 84. 40. 51. 51. 32. 45. 45. 44. + 34. 65. 128. 182. 168. 154. 168. 178. 198. 202. 201. 199. 197. 195. + 193. 193. 192. 195. 195. 196. 194. 192. 192. 194. 195. 200. 198. + 195. 195. 198. 201. 201. 199. 202. 197. 203. 209. 210. 213. 206. + 186. 168. 143. 114. 99. 92. 88. 83. 81. 91. 89. 95. 122. 156. 177. + 200. 229. 194. 66. 44. 38. 42. 56. 45. 51. 50. 50. 48. 47. 50. 53. + 50. 44. 40. 60. 96. 133. 150. 148. 143. 143. 150. 155. 161. 163. + 161. 159. 159. 160. 159. 159. 159. 158. 157. 156. 156. 155. 155. + 155. 155. 155. 154. 154. 154. 153. 154. 154. 154. 154. 154. 154. + 154. 154. 98. 100. 103. 104. 103. 101. 98. 95. 100. 103. 105. 107. + 112. 122. 135. 145. 153. 160. 168. 172. 172. 172. 173. 175. 173. + 173. 170. 165. 158. 146. 125. 107. 86. 77. 72. 77. 85. 90. 93. 96. + 95. 97. 98. 98. 98. 98. 99. 101. 96. 97. 99. 100. 100. 99. 97. 97. + 101. 80. 82. 114. 220. 205. 198. 197. 198. 195. 185. 163. 134. 115. + 117. 129. 131. 117. 108. 111. 117. 118. 114. 113. 107. 114. 125. + 134. 139. 138. 134. 132. 125. 123. 122. 126. 132. 136. 136. 135. + 131. 132. 129. 134. 140. 148. 138. 125. 99. 116. 138. 142. 123. 104. + 111. 130. 126. 105. 134. 131. 124. 89. 82. 90. 94. 99. 113. 103. + 102. 78. 70. 57. 56. 108. 101. 59. 83. 82. 80. 66. 54. 44. 35. 34. + 41. 40. 67. 107. 142. 175. 170. 136. 163. 201. 197. 209. 198. 197. + 195. 194. 192. 192. 192. 192. 193. 194. 195. 193. 192. 192. 193. + 195. 194. 198. 200. 199. 199. 200. 197. 193. 200. 197. 206. 213. + 207. 192. 161. 124. 103. 90. 80. 82. 89. 92. 91. 91. 93. 114. 127. + 150. 187. 196. 188. 192. 107. 32. 57. 41. 44. 58. 55. 51. 52. 50. + 48. 49. 53. 53. 47. 39. 39. 71. 115. 145. 151. 145. 142. 144. 155. + 159. 162. 163. 161. 159. 158. 159. 160. 160. 159. 158. 157. 157. + 156. 156. 156. 156. 155. 155. 155. 154. 154. 154. 155. 155. 154. + 154. 154. 154. 153. 153. 99. 101. 103. 104. 103. 100. 96. 94. 100. + 103. 105. 107. 112. 122. 135. 145. 153. 160. 168. 172. 172. 171. + 173. 174. 173. 173. 170. 165. 158. 146. 125. 107. 87. 78. 73. 78. + 86. 91. 94. 96. 95. 97. 98. 98. 98. 98. 99. 101. 99. 99. 100. 100. + 99. 97. 95. 94. 97. 81. 81. 97. 209. 210. 198. 199. 200. 196. 184. + 160. 130. 112. 119. 134. 137. 129. 122. 122. 122. 118. 112. 108. + 116. 124. 133. 137. 137. 133. 131. 130. 119. 120. 123. 130. 136. + 138. 135. 131. 124. 130. 139. 139. 142. 135. 126. 115. 127. 132. + 128. 116. 112. 121. 130. 131. 120. 97. 110. 87. 84. 68. 66. 63. 72. + 84. 108. 105. 106. 86. 91. 90. 113. 83. 83. 85. 65. 45. 86. 73. 59. + 43. 31. 42. 37. 39. 94. 180. 179. 136. 152. 174. 176. 194. 202. 200. + 193. 193. 193. 193. 193. 192. 190. 189. 192. 193. 193. 193. 191. + 191. 193. 195. 190. 198. 203. 199. 197. 200. 202. 201. 208. 212. + 214. 190. 147. 116. 99. 83. 87. 83. 84. 90. 96. 97. 98. 101. 117. + 156. 168. 172. 202. 199. 135. 73. 40. 36. 53. 39. 52. 46. 51. 47. + 51. 48. 47. 51. 55. 53. 46. 39. 46. 85. 129. 151. 149. 143. 144. + 148. 160. 162. 163. 162. 161. 159. 159. 159. 160. 160. 159. 159. + 158. 157. 156. 156. 156. 156. 156. 155. 155. 155. 154. 154. 155. + 155. 155. 154. 154. 153. 153. 153. 101. 102. 103. 103. 102. 99. 96. + 94. 102. 104. 106. 109. 113. 123. 137. 146. 153. 159. 167. 171. 172. + 171. 172. 174. 173. 173. 170. 165. 158. 146. 125. 107. 87. 78. 73. + 78. 86. 91. 94. 97. 95. 97. 98. 98. 98. 98. 99. 101. 100. 100. 100. + 100. 99. 97. 95. 93. 96. 88. 85. 87. 187. 214. 203. 203. 205. 197. + 181. 156. 129. 119. 132. 151. 142. 138. 131. 124. 117. 111. 108. + 107. 122. 130. 139. 143. 139. 132. 125. 122. 121. 123. 128. 133. + 135. 134. 129. 124. 125. 130. 145. 141. 139. 118. 117. 116. 134. + 140. 134. 118. 116. 123. 115. 97. 86. 73. 72. 50. 57. 64. 63. 68. + 77. 103. 105. 130. 93. 102. 91. 112. 75. 118. 97. 63. 69. 49. 84. + 99. 32. 49. 33. 29. 55. 119. 150. 165. 127. 135. 176. 196. 194. 191. + 182. 190. 193. 194. 195. 195. 193. 191. 187. 185. 191. 192. 192. + 192. 190. 191. 193. 195. 193. 200. 200. 194. 194. 202. 208. 207. + 214. 202. 181. 141. 97. 82. 87. 87. 85. 84. 87. 93. 99. 107. 121. + 134. 152. 169. 195. 215. 200. 136. 65. 31. 37. 52. 37. 44. 65. 40. + 45. 50. 48. 46. 47. 54. 57. 54. 48. 46. 65. 103. 141. 152. 146. 144. + 149. 154. 164. 164. 163. 162. 161. 160. 160. 160. 161. 160. 160. + 159. 158. 157. 157. 157. 157. 156. 156. 156. 155. 155. 155. 155. + 156. 156. 155. 154. 154. 153. 152. 152. 105. 105. 104. 103. 102. 99. + 97. 96. 101. 103. 106. 108. 112. 122. 136. 145. 152. 159. 167. 171. + 171. 171. 172. 174. 173. 173. 170. 165. 158. 146. 125. 107. 87. 79. + 73. 78. 86. 91. 94. 97. 95. 97. 98. 98. 98. 98. 99. 101. 98. 99. + 100. 100. 99. 98. 96. 95. 98. 96. 87. 80. 158. 214. 205. 203. 203. + 196. 182. 160. 136. 126. 137. 153. 144. 142. 134. 120. 107. 104. + 108. 114. 129. 134. 139. 140. 135. 129. 123. 119. 124. 127. 131. + 133. 131. 128. 126. 125. 137. 131. 143. 135. 132. 104. 116. 128. + 124. 133. 132. 116. 99. 90. 86. 81. 88. 83. 68. 55. 56. 61. 47. 73. + 107. 103. 122. 89. 91. 58. 88. 100. 116. 92. 77. 90. 82. 45. 82. 71. + 23. 46. 38. 62. 114. 183. 165. 129. 117. 179. 205. 183. 192. 196. + 173. 187. 192. 193. 193. 192. 191. 189. 186. 185. 190. 191. 192. + 191. 190. 190. 192. 194. 194. 198. 197. 193. 196. 202. 196. 183. + 169. 154. 139. 117. 96. 96. 101. 96. 87. 91. 100. 113. 125. 137. + 153. 166. 177. 173. 199. 212. 149. 59. 33. 54. 48. 58. 38. 55. 61. + 49. 46. 51. 46. 45. 49. 57. 60. 56. 54. 56. 90. 123. 150. 151. 143. + 146. 155. 159. 166. 165. 163. 162. 162. 162. 162. 161. 161. 161. + 160. 159. 158. 158. 157. 157. 157. 157. 156. 156. 156. 155. 155. + 155. 156. 156. 155. 154. 154. 153. 152. 152. 108. 107. 106. 104. + 102. 100. 99. 98. 98. 100. 103. 105. 110. 119. 133. 142. 152. 159. + 167. 171. 171. 171. 172. 174. 173. 173. 170. 165. 158. 146. 125. + 107. 88. 79. 74. 79. 87. 91. 94. 97. 95. 97. 98. 98. 98. 98. 99. + 101. 96. 97. 98. 99. 100. 99. 98. 97. 99. 100. 87. 73. 134. 209. + 203. 201. 196. 193. 185. 169. 146. 130. 131. 140. 149. 148. 138. + 119. 104. 104. 116. 127. 138. 137. 135. 131. 128. 125. 124. 124. + 124. 127. 130. 130. 128. 126. 128. 130. 149. 132. 138. 127. 127. 98. + 119. 140. 139. 124. 102. 79. 62. 60. 75. 93. 83. 77. 51. 49. 50. 60. + 50. 104. 118. 113. 91. 77. 45. 50. 68. 101. 58. 105. 95. 69. 61. 41. + 81. 67. 47. 29. 46. 142. 174. 152. 113. 137. 189. 181. 199. 186. + 166. 181. 187. 184. 189. 188. 188. 187. 187. 187. 187. 187. 189. + 190. 191. 191. 190. 190. 192. 194. 192. 195. 196. 196. 202. 200. + 177. 149. 95. 111. 132. 130. 108. 97. 97. 92. 109. 116. 132. 150. + 162. 165. 167. 171. 188. 192. 194. 150. 73. 37. 43. 46. 39. 51. 51. + 61. 42. 58. 49. 43. 45. 45. 51. 60. 62. 58. 58. 64. 108. 136. 156. + 150. 141. 147. 158. 162. 167. 165. 162. 161. 162. 163. 163. 162. + 161. 161. 160. 159. 159. 158. 157. 157. 157. 157. 157. 156. 156. + 155. 155. 155. 156. 156. 155. 154. 154. 153. 152. 152. 108. 106. + 104. 104. 104. 104. 102. 100. 99. 101. 104. 106. 111. 121. 134. 144. + 153. 160. 167. 171. 170. 169. 168. 169. 171. 172. 169. 163. 157. + 146. 127. 110. 85. 79. 76. 80. 85. 87. 92. 97. 93. 94. 95. 96. 97. + 97. 97. 97. 100. 99. 98. 97. 98. 99. 100. 101. 100. 94. 102. 71. 91. + 201. 199. 210. 198. 199. 184. 172. 160. 133. 128. 156. 136. 152. + 134. 104. 104. 114. 124. 140. 133. 136. 136. 129. 120. 116. 121. + 128. 127. 126. 129. 130. 125. 121. 130. 144. 135. 145. 134. 144. + 134. 87. 140. 134. 113. 89. 70. 54. 67. 98. 93. 69. 45. 70. 50. 49. + 64. 35. 90. 126. 110. 122. 70. 50. 42. 51. 102. 94. 70. 99. 90. 51. + 27. 32. 110. 86. 32. 82. 143. 167. 147. 130. 154. 192. 196. 193. + 188. 183. 180. 180. 183. 186. 185. 187. 188. 188. 187. 185. 185. + 186. 190. 189. 187. 186. 189. 195. 198. 199. 201. 197. 206. 180. + 199. 170. 76. 103. 106. 109. 139. 137. 135. 116. 136. 140. 153. 160. + 166. 169. 169. 168. 168. 167. 184. 202. 151. 63. 33. 46. 50. 45. 52. + 52. 53. 53. 53. 52. 51. 51. 37. 49. 53. 61. 65. 46. 47. 80. 132. + 144. 150. 145. 140. 147. 159. 165. 161. 163. 164. 165. 165. 163. + 161. 159. 161. 161. 160. 159. 159. 158. 157. 157. 159. 158. 156. + 155. 154. 155. 156. 157. 156. 156. 155. 154. 154. 153. 152. 152. + 108. 106. 105. 104. 104. 104. 102. 100. 100. 102. 104. 106. 111. + 121. 134. 144. 153. 160. 167. 171. 171. 169. 169. 170. 171. 172. + 169. 163. 157. 147. 127. 110. 86. 78. 75. 79. 85. 89. 92. 95. 94. + 95. 96. 98. 98. 99. 99. 99. 99. 99. 97. 97. 97. 98. 100. 101. 98. + 95. 94. 80. 83. 169. 216. 196. 188. 196. 194. 185. 173. 154. 136. + 134. 149. 136. 111. 100. 116. 130. 133. 135. 142. 134. 123. 113. + 111. 116. 125. 132. 129. 132. 129. 121. 119. 124. 126. 122. 136. + 133. 134. 152. 153. 109. 122. 97. 80. 61. 65. 85. 93. 75. 51. 46. + 56. 57. 46. 47. 54. 54. 114. 104. 109. 86. 46. 40. 71. 107. 108. 73. + 80. 89. 67. 38. 45. 52. 94. 72. 89. 145. 169. 139. 125. 157. 191. + 196. 190. 188. 185. 181. 179. 181. 184. 187. 183. 184. 185. 184. + 183. 183. 186. 188. 185. 190. 193. 193. 192. 191. 188. 184. 188. + 188. 207. 162. 82. 80. 101. 76. 104. 105. 120. 145. 152. 160. 161. + 160. 163. 159. 161. 168. 168. 166. 177. 192. 222. 156. 71. 30. 36. + 46. 45. 47. 55. 55. 55. 54. 52. 50. 47. 46. 48. 54. 51. 51. 52. 44. + 59. 101. 137. 146. 150. 145. 143. 151. 161. 167. 162. 164. 165. 166. + 165. 164. 162. 160. 161. 161. 160. 160. 159. 158. 157. 157. 159. + 158. 156. 155. 155. 155. 156. 156. 156. 156. 155. 154. 154. 153. + 152. 152. 109. 107. 105. 104. 105. 104. 102. 100. 101. 102. 104. + 106. 110. 121. 134. 144. 153. 159. 168. 172. 171. 169. 169. 170. + 172. 172. 169. 164. 158. 147. 128. 111. 87. 78. 72. 78. 86. 91. 92. + 93. 95. 96. 97. 99. 99. 100. 100. 99. 98. 98. 97. 96. 97. 98. 100. + 101. 100. 100. 90. 91. 79. 126. 225. 194. 200. 202. 199. 184. 171. + 172. 164. 142. 163. 125. 104. 113. 127. 135. 137. 132. 140. 128. + 113. 108. 112. 121. 128. 130. 126. 132. 127. 115. 120. 133. 130. + 113. 92. 97. 128. 140. 129. 94. 90. 83. 58. 72. 76. 76. 75. 61. 44. + 40. 68. 45. 42. 46. 50. 76. 129. 71. 84. 48. 48. 63. 95. 122. 104. + 87. 93. 45. 49. 61. 53. 51. 96. 109. 160. 152. 139. 137. 157. 185. + 200. 199. 185. 183. 181. 179. 179. 182. 185. 187. 181. 181. 180. + 179. 179. 181. 186. 189. 191. 193. 191. 188. 190. 196. 199. 198. + 203. 176. 97. 74. 66. 75. 125. 110. 105. 110. 110. 147. 153. 176. + 163. 164. 167. 170. 171. 169. 170. 180. 198. 212. 160. 82. 30. 35. + 46. 44. 45. 53. 54. 55. 56. 55. 53. 50. 46. 44. 52. 57. 52. 46. 44. + 46. 75. 120. 144. 147. 147. 145. 147. 156. 165. 168. 164. 165. 166. + 166. 166. 165. 163. 162. 161. 161. 161. 160. 159. 158. 158. 157. + 158. 158. 157. 156. 155. 155. 156. 156. 156. 156. 155. 154. 154. + 153. 152. 152. 109. 107. 105. 105. 105. 104. 102. 100. 101. 102. + 103. 105. 109. 120. 134. 144. 153. 159. 168. 172. 171. 170. 170. + 171. 172. 172. 170. 164. 158. 147. 128. 111. 88. 77. 70. 76. 87. 92. + 92. 91. 95. 96. 97. 98. 99. 99. 99. 99. 98. 97. 96. 96. 96. 98. 100. + 101. 105. 104. 96. 96. 87. 94. 200. 209. 210. 200. 195. 180. 164. + 175. 182. 162. 147. 110. 108. 129. 128. 126. 135. 138. 125. 120. + 116. 119. 125. 128. 125. 121. 119. 124. 124. 121. 130. 142. 140. + 127. 130. 91. 97. 103. 113. 109. 71. 50. 69. 94. 82. 62. 54. 52. 62. + 66. 69. 42. 40. 48. 65. 85. 110. 46. 61. 38. 59. 97. 101. 93. 97. + 106. 73. 36. 80. 82. 33. 68. 145. 159. 153. 119. 119. 166. 199. 194. + 188. 198. 184. 182. 180. 179. 180. 182. 184. 184. 178. 177. 176. + 175. 175. 179. 185. 190. 194. 193. 189. 186. 192. 200. 196. 185. + 139. 62. 38. 105. 87. 69. 135. 126. 107. 117. 118. 138. 146. 160. + 156. 164. 170. 174. 170. 169. 188. 207. 194. 164. 63. 35. 38. 54. + 49. 45. 51. 50. 50. 52. 54. 54. 54. 51. 48. 46. 47. 53. 56. 51. 47. + 55. 89. 127. 147. 145. 143. 145. 152. 160. 166. 168. 165. 166. 166. + 167. 166. 165. 164. 163. 162. 162. 161. 160. 159. 159. 158. 158. + 158. 158. 157. 157. 156. 156. 156. 156. 156. 156. 155. 154. 154. + 153. 152. 152. 110. 108. 106. 105. 105. 105. 103. 101. 101. 102. + 102. 103. 107. 118. 132. 143. 152. 159. 168. 172. 172. 171. 171. + 172. 172. 173. 170. 165. 158. 148. 129. 111. 88. 76. 70. 76. 87. 92. + 92. 91. 93. 94. 95. 97. 98. 98. 98. 98. 97. 97. 96. 96. 97. 99. 101. + 102. 107. 103. 104. 93. 97. 81. 148. 218. 206. 195. 196. 187. 167. + 169. 177. 167. 122. 96. 106. 133. 129. 123. 132. 137. 109. 114. 122. + 128. 131. 127. 121. 116. 119. 120. 125. 133. 137. 137. 136. 136. + 102. 79. 96. 86. 70. 79. 67. 85. 85. 87. 68. 72. 62. 44. 70. 93. 52. + 41. 39. 51. 91. 83. 74. 41. 55. 55. 56. 92. 88. 77. 104. 79. 34. 96. + 121. 55. 31. 123. 172. 150. 107. 134. 169. 191. 195. 192. 190. 192. + 186. 184. 181. 180. 182. 183. 181. 180. 175. 175. 174. 174. 175. + 179. 185. 190. 187. 190. 191. 193. 198. 191. 162. 129. 82. 39. 56. + 114. 104. 77. 105. 136. 115. 119. 121. 118. 148. 152. 162. 170. 174. + 168. 169. 187. 203. 186. 129. 75. 48. 32. 39. 48. 42. 46. 54. 46. + 51. 52. 53. 53. 52. 50. 48. 46. 46. 50. 56. 54. 51. 68. 104. 131. + 144. 141. 140. 146. 156. 163. 166. 166. 166. 166. 166. 166. 165. + 165. 164. 164. 162. 162. 161. 161. 160. 159. 158. 158. 158. 158. + 158. 158. 157. 157. 156. 156. 156. 156. 155. 154. 154. 153. 152. + 152. 110. 108. 106. 105. 106. 105. 103. 101. 101. 101. 101. 101. + 105. 115. 130. 141. 152. 159. 168. 172. 173. 171. 172. 173. 173. + 173. 170. 165. 159. 148. 129. 112. 86. 76. 71. 76. 85. 90. 91. 92. + 93. 94. 95. 96. 97. 97. 97. 97. 98. 97. 97. 97. 98. 100. 102. 104. + 106. 101. 106. 94. 100. 83. 103. 189. 213. 208. 202. 187. 168. 168. + 177. 178. 127. 112. 115. 133. 137. 131. 125. 120. 108. 115. 123. + 127. 126. 123. 120. 120. 123. 123. 130. 138. 134. 123. 120. 125. 99. + 63. 57. 61. 65. 93. 75. 76. 79. 80. 55. 54. 47. 57. 99. 89. 34. 40. + 41. 54. 105. 77. 49. 49. 45. 73. 62. 68. 55. 72. 109. 44. 33. 140. + 105. 40. 80. 141. 124. 118. 136. 173. 202. 200. 192. 193. 194. 188. + 187. 184. 181. 181. 182. 182. 179. 175. 172. 174. 175. 176. 177. + 180. 184. 187. 189. 190. 187. 186. 191. 187. 156. 120. 85. 96. 79. + 61. 104. 113. 86. 124. 130. 125. 115. 100. 148. 152. 162. 165. 167. + 173. 195. 209. 172. 100. 51. 40. 51. 37. 40. 51. 46. 40. 49. 60. 57. + 56. 55. 52. 50. 47. 44. 43. 54. 50. 53. 53. 54. 83. 121. 137. 138. + 135. 138. 150. 161. 166. 166. 165. 166. 165. 165. 165. 164. 164. + 164. 164. 163. 162. 162. 161. 160. 159. 159. 159. 158. 158. 159. + 159. 158. 157. 156. 156. 156. 156. 155. 154. 154. 153. 152. 152. + 110. 108. 106. 106. 106. 105. 104. 102. 100. 100. 99. 98. 102. 113. + 128. 139. 152. 159. 168. 173. 173. 172. 172. 174. 173. 173. 171. + 165. 159. 148. 129. 112. 84. 77. 73. 77. 84. 87. 90. 93. 94. 95. 96. + 97. 98. 98. 98. 98. 99. 98. 98. 98. 99. 102. 104. 105. 106. 102. + 105. 105. 96. 93. 87. 130. 204. 219. 209. 183. 175. 181. 182. 180. + 130. 135. 131. 129. 136. 132. 119. 113. 117. 121. 126. 128. 127. + 125. 124. 125. 120. 127. 133. 133. 127. 120. 113. 108. 107. 101. 97. + 94. 61. 71. 72. 88. 63. 69. 44. 34. 32. 80. 128. 69. 33. 40. 50. 57. + 97. 70. 45. 52. 46. 64. 67. 55. 39. 74. 99. 35. 66. 132. 86. 90. + 123. 110. 92. 130. 189. 190. 194. 197. 198. 195. 188. 183. 185. 181. + 178. 179. 182. 182. 177. 172. 170. 174. 178. 181. 182. 182. 183. + 184. 188. 189. 183. 177. 184. 193. 179. 156. 86. 72. 102. 97. 76. + 100. 104. 82. 129. 135. 114. 103. 136. 150. 153. 168. 175. 186. 192. + 165. 99. 39. 28. 48. 36. 42. 49. 57. 57. 45. 47. 65. 59. 57. 54. 50. + 47. 45. 44. 44. 59. 50. 54. 57. 64. 99. 133. 137. 131. 131. 140. + 156. 167. 168. 166. 166. 165. 165. 164. 163. 163. 163. 163. 163. + 163. 163. 162. 161. 160. 160. 159. 159. 158. 158. 159. 159. 159. + 158. 156. 155. 156. 156. 155. 154. 154. 153. 152. 152. 110. 108. + 106. 106. 106. 106. 104. 102. 99. 99. 98. 97. 101. 112. 127. 138. + 152. 159. 168. 173. 173. 172. 173. 174. 173. 174. 171. 165. 159. + 148. 129. 112. 82. 77. 74. 78. 83. 85. 90. 95. 95. 96. 97. 98. 99. + 100. 99. 99. 99. 99. 99. 99. 100. 103. 105. 106. 107. 106. 103. 118. + 93. 102. 92. 81. 166. 209. 211. 188. 192. 197. 176. 156. 106. 134. + 134. 120. 125. 127. 120. 124. 124. 127. 130. 133. 134. 132. 129. + 126. 113. 127. 133. 125. 123. 127. 118. 101. 91. 89. 78. 89. 66. 83. + 90. 100. 55. 40. 27. 55. 57. 86. 126. 59. 41. 42. 60. 58. 82. 65. + 49. 48. 69. 40. 51. 51. 51. 90. 86. 35. 88. 120. 109. 153. 121. 89. + 124. 163. 185. 196. 197. 189. 187. 192. 189. 178. 181. 178. 176. + 178. 181. 181. 176. 171. 169. 174. 180. 184. 185. 184. 183. 183. + 175. 185. 189. 185. 190. 199. 188. 169. 131. 93. 74. 94. 111. 105. + 101. 107. 113. 141. 120. 119. 127. 152. 155. 191. 201. 190. 143. 77. + 40. 43. 49. 42. 42. 56. 48. 42. 59. 63. 50. 48. 56. 54. 51. 48. 47. + 47. 48. 49. 58. 49. 56. 66. 76. 112. 139. 131. 126. 129. 141. 160. + 172. 170. 167. 167. 165. 164. 163. 162. 162. 162. 162. 163. 163. + 163. 162. 161. 161. 160. 159. 159. 157. 158. 159. 160. 159. 158. + 156. 155. 156. 156. 155. 154. 154. 153. 152. 152. 109. 109. 108. + 107. 105. 103. 101. 100. 103. 101. 97. 94. 97. 109. 126. 139. 151. + 158. 166. 171. 171. 170. 170. 171. 175. 176. 174. 167. 158. 147. + 129. 114. 89. 74. 72. 79. 80. 86. 93. 90. 94. 95. 96. 97. 97. 97. + 96. 96. 98. 98. 98. 99. 101. 103. 105. 106. 110. 113. 112. 108. 105. + 102. 95. 86. 106. 202. 206. 196. 193. 193. 196. 129. 139. 129. 121. + 118. 117. 115. 117. 121. 125. 129. 133. 131. 122. 114. 115. 120. + 123. 126. 116. 109. 119. 118. 97. 79. 63. 79. 84. 79. 86. 99. 93. + 72. 57. 50. 50. 27. 57. 100. 109. 50. 37. 61. 84. 48. 51. 46. 59. + 66. 88. 79. 93. 93. 66. 104. 85. 67. 96. 108. 107. 144. 117. 123. + 161. 174. 187. 185. 185. 189. 192. 191. 185. 178. 178. 179. 180. + 179. 178. 176. 175. 174. 172. 178. 184. 185. 183. 181. 181. 183. + 191. 190. 191. 195. 198. 196. 187. 180. 141. 110. 88. 80. 89. 118. + 116. 76. 85. 128. 134. 143. 119. 148. 179. 178. 161. 100. 54. 44. + 41. 40. 45. 48. 45. 45. 52. 59. 58. 52. 53. 59. 58. 54. 48. 44. 44. + 47. 48. 49. 51. 54. 55. 63. 91. 123. 135. 129. 117. 132. 152. 165. + 168. 167. 167. 169. 163. 164. 164. 164. 164. 164. 165. 165. 163. + 163. 163. 163. 163. 162. 160. 160. 159. 159. 158. 158. 158. 157. + 157. 157. 155. 154. 154. 153. 153. 152. 152. 151. 108. 108. 108. + 107. 105. 103. 101. 100. 102. 100. 96. 93. 96. 108. 125. 138. 151. + 158. 166. 171. 171. 170. 170. 172. 175. 176. 173. 167. 158. 147. + 129. 114. 88. 73. 71. 78. 79. 85. 92. 89. 94. 95. 96. 97. 97. 97. + 97. 96. 97. 97. 98. 99. 101. 103. 104. 106. 108. 111. 111. 108. 106. + 104. 98. 89. 95. 191. 208. 204. 196. 190. 199. 153. 139. 128. 121. + 120. 114. 105. 109. 122. 129. 125. 118. 113. 111. 114. 121. 128. + 137. 127. 124. 129. 122. 99. 73. 58. 70. 72. 73. 77. 87. 93. 86. 73. + 52. 47. 51. 40. 67. 80. 86. 60. 58. 61. 74. 53. 57. 47. 52. 48. 46. + 72. 63. 44. 56. 91. 60. 66. 100. 95. 98. 127. 127. 145. 171. 175. + 179. 179. 181. 184. 185. 183. 178. 174. 175. 173. 172. 173. 174. + 174. 173. 172. 179. 177. 175. 176. 180. 185. 190. 193. 192. 191. + 192. 196. 200. 199. 193. 187. 165. 124. 96. 84. 76. 88. 100. 92. 79. + 90. 130. 133. 129. 147. 157. 149. 124. 74. 42. 44. 47. 47. 49. 49. + 49. 49. 53. 59. 57. 52. 53. 58. 56. 51. 46. 43. 44. 48. 51. 52. 52. + 52. 57. 74. 103. 128. 134. 128. 121. 135. 154. 166. 167. 165. 165. + 166. 164. 164. 164. 164. 164. 164. 164. 163. 162. 163. 163. 163. + 163. 162. 161. 160. 160. 159. 159. 159. 158. 158. 158. 157. 155. + 155. 154. 154. 153. 152. 152. 151. 108. 108. 107. 106. 105. 103. + 101. 100. 101. 99. 95. 92. 95. 107. 124. 137. 150. 157. 166. 171. + 171. 170. 171. 172. 175. 176. 173. 166. 159. 147. 130. 114. 87. 72. + 71. 77. 78. 85. 91. 88. 95. 96. 97. 97. 98. 98. 97. 97. 97. 97. 97. + 98. 100. 102. 104. 105. 107. 110. 111. 109. 108. 107. 101. 93. 84. + 178. 213. 212. 200. 192. 199. 172. 134. 125. 122. 122. 114. 103. + 110. 127. 128. 122. 114. 111. 116. 125. 132. 136. 123. 100. 114. + 138. 122. 92. 78. 70. 71. 61. 57. 68. 81. 84. 77. 70. 59. 53. 53. + 50. 75. 60. 69. 89. 91. 59. 44. 35. 41. 39. 51. 47. 40. 52. 40. 34. + 49. 71. 62. 95. 79. 70. 96. 110. 132. 152. 165. 165. 173. 177. 180. + 181. 179. 175. 172. 170. 174. 173. 172. 173. 175. 176. 175. 174. + 178. 173. 171. 175. 184. 193. 198. 198. 194. 193. 193. 197. 201. + 202. 198. 194. 183. 140. 109. 93. 68. 57. 75. 96. 88. 62. 122. 128. + 142. 148. 147. 132. 108. 64. 39. 43. 46. 44. 45. 43. 54. 53. 55. 58. + 57. 54. 54. 58. 54. 50. 44. 42. 44. 48. 52. 55. 52. 50. 62. 91. 121. + 134. 131. 125. 127. 140. 156. 166. 167. 164. 162. 162. 165. 165. + 165. 164. 163. 163. 162. 162. 162. 162. 163. 163. 163. 162. 161. + 160. 161. 160. 160. 160. 159. 159. 159. 158. 156. 155. 155. 154. + 153. 152. 151. 151. 107. 107. 106. 106. 104. 103. 101. 100. 100. 98. + 94. 90. 94. 106. 123. 136. 150. 157. 166. 171. 171. 170. 171. 173. + 174. 175. 173. 166. 159. 147. 130. 115. 88. 73. 72. 78. 79. 86. 92. + 89. 96. 96. 97. 98. 99. 99. 98. 98. 96. 96. 97. 98. 100. 102. 104. + 105. 108. 111. 112. 110. 109. 109. 103. 95. 82. 170. 218. 215. 206. + 203. 190. 162. 121. 124. 124. 121. 116. 116. 121. 125. 112. 117. + 122. 127. 133. 138. 136. 131. 128. 95. 105. 122. 97. 77. 76. 68. 61. + 52. 46. 53. 69. 79. 75. 65. 75. 71. 57. 47. 77. 54. 68. 115. 102. + 64. 41. 50. 55. 49. 57. 46. 55. 40. 46. 46. 38. 76. 107. 105. 79. + 83. 136. 135. 157. 165. 169. 178. 177. 182. 186. 184. 177. 170. 168. + 169. 170. 174. 178. 178. 174. 171. 172. 174. 168. 171. 178. 187. + 196. 199. 198. 195. 196. 194. 194. 197. 200. 200. 199. 196. 183. + 149. 120. 101. 73. 49. 55. 74. 99. 66. 99. 128. 141. 144. 154. 136. + 110. 69. 43. 41. 39. 40. 44. 45. 55. 55. 56. 57. 57. 57. 58. 60. 54. + 49. 44. 42. 44. 48. 52. 54. 50. 49. 68. 107. 135. 136. 126. 122. + 134. 144. 158. 166. 167. 165. 163. 163. 166. 165. 165. 164. 163. + 162. 161. 161. 161. 162. 163. 163. 163. 162. 161. 161. 161. 161. + 161. 160. 160. 160. 159. 159. 157. 156. 155. 154. 153. 152. 151. + 151. 106. 106. 106. 105. 104. 103. 101. 100. 100. 97. 93. 90. 93. + 105. 123. 136. 149. 156. 165. 171. 171. 171. 172. 173. 174. 175. + 173. 166. 159. 148. 131. 115. 90. 75. 73. 80. 81. 87. 94. 91. 97. + 97. 98. 99. 99. 99. 99. 99. 97. 97. 97. 98. 100. 102. 104. 105. 111. + 114. 115. 112. 111. 109. 103. 95. 88. 165. 221. 213. 212. 213. 171. + 129. 109. 122. 125. 115. 116. 129. 127. 113. 98. 114. 129. 137. 139. + 138. 130. 122. 121. 88. 82. 82. 64. 69. 82. 69. 49. 51. 45. 41. 57. + 80. 80. 64. 82. 84. 62. 41. 74. 55. 63. 106. 117. 86. 41. 44. 41. + 37. 52. 50. 45. 41. 44. 40. 55. 104. 126. 82. 108. 113. 159. 153. + 175. 175. 173. 186. 184. 188. 190. 184. 174. 166. 165. 167. 163. + 173. 181. 178. 168. 161. 164. 169. 167. 176. 188. 196. 199. 198. + 197. 196. 197. 196. 196. 197. 198. 198. 197. 196. 179. 156. 124. 98. + 79. 59. 47. 48. 88. 80. 70. 129. 132. 136. 161. 139. 97. 63. 43. 42. + 40. 43. 51. 53. 53. 54. 55. 56. 58. 61. 62. 61. 54. 50. 45. 43. 44. + 47. 49. 50. 48. 53. 79. 119. 141. 134. 123. 122. 140. 148. 157. 164. + 166. 165. 165. 166. 165. 165. 164. 163. 162. 161. 161. 160. 161. + 161. 162. 163. 163. 163. 162. 161. 161. 161. 161. 160. 160. 160. + 159. 159. 158. 157. 156. 155. 154. 152. 151. 151. 105. 105. 105. + 105. 104. 102. 101. 100. 100. 98. 93. 90. 93. 106. 123. 136. 149. + 156. 165. 170. 171. 171. 172. 174. 173. 174. 172. 166. 159. 148. + 131. 116. 90. 76. 74. 81. 82. 88. 95. 92. 97. 98. 99. 100. 100. 100. + 100. 99. 98. 98. 98. 99. 101. 103. 105. 106. 113. 116. 116. 113. + 112. 111. 105. 97. 95. 154. 218. 213. 215. 212. 145. 104. 104. 118. + 121. 110. 114. 127. 122. 104. 108. 122. 132. 133. 132. 132. 128. + 120. 106. 76. 55. 46. 48. 73. 84. 65. 42. 53. 50. 40. 51. 77. 83. + 69. 75. 84. 66. 42. 75. 56. 50. 69. 118. 120. 64. 56. 46. 36. 43. + 43. 38. 35. 26. 61. 124. 109. 97. 96. 147. 137. 144. 149. 178. 180. + 173. 184. 188. 189. 187. 179. 168. 162. 162. 164. 167. 176. 183. + 178. 166. 160. 164. 172. 177. 184. 192. 195. 195. 195. 198. 202. + 198. 199. 199. 200. 199. 199. 198. 197. 183. 167. 127. 92. 81. 67. + 47. 38. 64. 89. 59. 126. 136. 141. 166. 138. 79. 55. 46. 49. 46. 45. + 48. 47. 51. 54. 55. 56. 59. 64. 63. 60. 52. 49. 46. 45. 46. 47. 47. + 47. 50. 64. 96. 130. 141. 132. 126. 129. 146. 150. 155. 159. 161. + 162. 164. 166. 164. 164. 163. 163. 162. 161. 161. 161. 160. 161. + 162. 163. 163. 163. 162. 162. 161. 160. 160. 160. 159. 159. 159. + 158. 159. 158. 157. 155. 154. 152. 151. 151. 104. 104. 105. 104. + 104. 102. 101. 100. 101. 98. 94. 91. 94. 106. 124. 137. 148. 156. + 165. 170. 171. 171. 172. 174. 173. 174. 172. 166. 159. 148. 131. + 116. 90. 75. 74. 80. 81. 88. 94. 91. 98. 99. 99. 100. 101. 101. 100. + 100. 99. 99. 100. 101. 102. 104. 106. 107. 111. 115. 116. 114. 114. + 114. 108. 101. 97. 136. 211. 218. 215. 196. 119. 102. 104. 110. 113. + 113. 114. 117. 117. 114. 125. 130. 128. 120. 120. 126. 124. 115. + 118. 87. 52. 40. 56. 72. 60. 35. 41. 50. 52. 45. 49. 64. 75. 75. 69. + 76. 68. 51. 80. 59. 46. 50. 86. 140. 100. 97. 88. 65. 40. 24. 37. + 37. 55. 116. 159. 99. 106. 148. 174. 160. 131. 158. 187. 188. 182. + 192. 189. 187. 181. 173. 164. 160. 162. 164. 178. 180. 178. 173. + 166. 165. 172. 178. 187. 189. 191. 193. 195. 197. 200. 202. 199. + 201. 204. 205. 205. 204. 204. 204. 191. 178. 137. 100. 87. 66. 44. + 42. 47. 84. 67. 105. 144. 153. 165. 139. 69. 51. 48. 52. 47. 44. 46. + 42. 51. 55. 56. 56. 60. 64. 62. 55. 47. 46. 45. 46. 48. 49. 48. 47. + 55. 79. 115. 139. 140. 131. 132. 141. 152. 152. 153. 153. 154. 156. + 160. 162. 163. 162. 162. 162. 162. 162. 162. 162. 160. 161. 162. + 163. 163. 163. 163. 162. 160. 159. 159. 159. 158. 158. 158. 157. + 159. 159. 157. 156. 154. 152. 151. 151. 104. 104. 104. 104. 103. + 102. 101. 100. 101. 99. 95. 91. 95. 107. 124. 137. 148. 155. 165. + 170. 171. 171. 173. 174. 172. 174. 172. 166. 159. 148. 132. 117. 89. + 74. 72. 79. 80. 86. 93. 90. 98. 99. 100. 101. 101. 101. 101. 100. + 100. 100. 100. 102. 103. 105. 107. 108. 109. 113. 115. 114. 115. + 116. 111. 104. 96. 122. 205. 223. 215. 180. 104. 111. 106. 102. 108. + 119. 117. 110. 116. 133. 130. 128. 117. 106. 108. 117. 114. 101. + 106. 77. 43. 45. 79. 88. 62. 38. 42. 45. 49. 49. 47. 51. 63. 77. 69. + 70. 67. 59. 84. 63. 52. 54. 73. 136. 72. 50. 48. 45. 38. 37. 20. 57. + 123. 150. 129. 100. 164. 178. 160. 156. 115. 158. 178. 173. 171. + 186. 189. 185. 178. 169. 163. 162. 164. 166. 183. 176. 167. 161. + 161. 167. 174. 178. 189. 188. 190. 195. 201. 203. 200. 197. 200. + 203. 207. 210. 210. 210. 210. 210. 194. 185. 148. 114. 95. 63. 39. + 46. 39. 71. 73. 76. 144. 159. 160. 139. 61. 45. 44. 49. 46. 48. 54. + 53. 52. 56. 57. 56. 60. 64. 59. 51. 43. 43. 44. 47. 50. 51. 49. 47. + 59. 91. 128. 145. 140. 132. 138. 150. 155. 154. 151. 149. 149. 151. + 155. 158. 161. 161. 162. 162. 162. 162. 162. 163. 160. 160. 162. + 163. 163. 163. 163. 163. 159. 159. 158. 158. 158. 157. 157. 157. + 160. 159. 158. 156. 154. 152. 151. 150. 100. 101. 104. 105. 106. + 105. 103. 101. 99. 98. 95. 92. 94. 106. 125. 139. 148. 156. 165. + 171. 173. 173. 174. 176. 177. 173. 174. 170. 157. 148. 135. 114. 92. + 76. 72. 77. 79. 86. 95. 93. 95. 97. 100. 102. 103. 102. 101. 100. + 97. 99. 104. 106. 101. 96. 100. 109. 142. 122. 110. 113. 117. 112. + 109. 111. 100. 98. 187. 224. 210. 151. 121. 104. 116. 121. 114. 100. + 102. 120. 131. 128. 132. 120. 105. 94. 63. 92. 81. 64. 78. 81. 59. + 43. 94. 77. 44. 33. 41. 50. 59. 52. 40. 48. 60. 56. 75. 57. 56. 62. + 85. 66. 65. 54. 63. 129. 81. 46. 18. 54. 32. 25. 44. 108. 155. 127. + 105. 162. 197. 160. 159. 173. 134. 150. 168. 155. 180. 189. 183. + 176. 170. 168. 165. 164. 168. 175. 176. 161. 153. 162. 170. 171. + 175. 184. 187. 190. 196. 199. 200. 200. 201. 202. 201. 202. 204. + 206. 207. 209. 209. 209. 202. 189. 161. 126. 95. 72. 53. 40. 38. 50. + 75. 70. 117. 157. 171. 152. 66. 47. 54. 51. 49. 59. 56. 57. 49. 52. + 56. 61. 64. 62. 57. 53. 42. 51. 51. 50. 56. 52. 44. 47. 65. 104. + 139. 144. 131. 128. 142. 157. 159. 156. 153. 150. 148. 148. 149. + 150. 153. 154. 155. 157. 158. 160. 161. 162. 165. 164. 163. 161. + 160. 160. 160. 160. 159. 159. 159. 158. 158. 157. 157. 157. 157. + 157. 156. 156. 154. 152. 151. 150. 102. 102. 104. 104. 104. 103. + 102. 101. 99. 99. 96. 93. 94. 106. 125. 140. 148. 156. 165. 171. + 173. 173. 174. 176. 177. 173. 174. 170. 157. 148. 135. 114. 92. 76. + 73. 78. 80. 87. 96. 94. 97. 99. 101. 103. 104. 103. 102. 101. 103. + 101. 100. 99. 98. 101. 115. 130. 134. 119. 110. 114. 117. 112. 110. + 113. 102. 103. 155. 213. 219. 143. 118. 107. 119. 119. 113. 107. + 111. 124. 130. 128. 126. 114. 98. 95. 77. 92. 70. 49. 63. 56. 51. + 53. 106. 66. 42. 49. 59. 56. 58. 56. 47. 48. 54. 54. 55. 66. 61. 50. + 85. 92. 93. 62. 43. 93. 82. 40. 35. 36. 26. 46. 105. 140. 134. 120. + 151. 176. 172. 171. 163. 171. 132. 150. 177. 168. 186. 186. 189. + 178. 170. 171. 173. 172. 170. 169. 160. 155. 157. 167. 172. 172. + 180. 192. 187. 190. 195. 197. 198. 199. 201. 202. 202. 203. 205. + 207. 208. 209. 210. 210. 205. 194. 170. 136. 104. 79. 57. 41. 31. + 46. 57. 73. 93. 157. 165. 145. 78. 54. 56. 51. 49. 58. 53. 53. 55. + 56. 59. 63. 65. 63. 57. 51. 42. 45. 43. 48. 57. 51. 42. 46. 77. 114. + 143. 142. 130. 133. 148. 160. 158. 157. 154. 151. 149. 148. 148. + 148. 150. 151. 152. 153. 155. 156. 157. 158. 160. 159. 159. 159. + 160. 161. 162. 162. 161. 161. 160. 159. 158. 157. 156. 155. 156. + 156. 156. 155. 154. 152. 151. 150. 104. 104. 104. 103. 102. 102. + 101. 101. 99. 98. 96. 92. 94. 106. 125. 140. 148. 156. 165. 171. + 173. 173. 174. 176. 177. 173. 174. 170. 157. 148. 135. 114. 93. 78. + 75. 80. 81. 89. 97. 95. 99. 100. 102. 104. 105. 105. 104. 103. 105. + 101. 98. 97. 98. 105. 122. 139. 124. 115. 112. 116. 117. 113. 113. + 117. 107. 109. 118. 188. 227. 147. 115. 114. 117. 115. 113. 115. + 121. 126. 129. 128. 139. 133. 114. 112. 93. 85. 61. 49. 58. 37. 44. + 52. 104. 47. 34. 53. 68. 59. 55. 56. 53. 49. 49. 52. 46. 67. 54. 45. + 94. 106. 108. 77. 58. 87. 120. 53. 42. 18. 41. 97. 149. 143. 125. + 142. 182. 181. 165. 179. 167. 176. 141. 152. 177. 173. 188. 190. + 191. 176. 165. 167. 173. 170. 160. 153. 149. 153. 164. 174. 174. + 172. 182. 196. 189. 191. 194. 196. 197. 198. 201. 203. 202. 204. + 205. 207. 209. 210. 211. 211. 208. 200. 178. 146. 113. 84. 59. 42. + 31. 47. 44. 80. 73. 159. 168. 144. 91. 61. 57. 50. 49. 58. 51. 50. + 61. 60. 60. 64. 67. 65. 57. 49. 46. 42. 40. 50. 60. 49. 42. 52. 96. + 128. 148. 139. 130. 141. 157. 163. 159. 158. 156. 154. 152. 150. + 149. 148. 147. 148. 148. 149. 150. 151. 152. 152. 152. 153. 154. + 155. 157. 160. 162. 163. 162. 161. 160. 159. 157. 156. 155. 154. + 156. 156. 156. 155. 154. 152. 151. 150. 106. 105. 104. 102. 101. + 100. 100. 100. 98. 97. 94. 91. 93. 105. 123. 138. 148. 156. 165. + 171. 173. 173. 174. 176. 177. 173. 174. 170. 157. 148. 135. 114. 94. + 78. 76. 82. 83. 90. 98. 95. 99. 100. 102. 103. 104. 104. 104. 103. + 100. 99. 100. 103. 103. 105. 115. 126. 115. 113. 114. 119. 119. 115. + 116. 121. 115. 111. 101. 154. 219. 171. 115. 121. 110. 110. 116. + 124. 127. 125. 126. 131. 127. 125. 105. 98. 76. 55. 54. 59. 56. 36. + 42. 37. 93. 52. 48. 51. 57. 59. 54. 50. 53. 51. 48. 51. 58. 59. 37. + 52. 103. 88. 94. 85. 74. 87. 151. 72. 24. 25. 85. 144. 138. 118. + 143. 179. 176. 175. 184. 178. 171. 183. 154. 151. 167. 168. 186. + 198. 190. 175. 163. 163. 166. 161. 151. 144. 154. 159. 169. 176. + 175. 172. 180. 192. 192. 193. 195. 196. 197. 199. 202. 205. 203. + 204. 206. 208. 210. 211. 211. 212. 210. 203. 183. 151. 117. 87. 62. + 45. 36. 44. 41. 77. 66. 149. 176. 146. 98. 62. 53. 48. 49. 59. 52. + 51. 63. 60. 59. 63. 66. 64. 56. 48. 50. 46. 45. 56. 60. 46. 45. 67. + 115. 139. 149. 135. 131. 148. 163. 165. 161. 161. 160. 158. 156. + 154. 152. 150. 147. 148. 148. 148. 148. 149. 149. 149. 147. 148. + 148. 150. 152. 155. 157. 159. 159. 158. 158. 157. 156. 156. 155. + 155. 155. 155. 155. 155. 154. 152. 151. 150. 107. 105. 104. 102. + 100. 99. 99. 99. 96. 95. 92. 89. 91. 103. 122. 136. 148. 156. 165. + 171. 173. 173. 174. 176. 177. 173. 174. 170. 157. 148. 135. 114. 93. + 78. 77. 83. 84. 91. 98. 95. 99. 100. 101. 102. 102. 103. 103. 103. + 100. 99. 102. 105. 105. 105. 110. 118. 112. 114. 117. 121. 120. 117. + 118. 122. 122. 109. 108. 125. 191. 196. 115. 124. 107. 114. 125. + 133. 131. 126. 127. 134. 114. 100. 74. 70. 61. 48. 76. 82. 43. 41. + 45. 29. 83. 79. 75. 50. 47. 64. 58. 46. 50. 52. 50. 54. 68. 60. 33. + 55. 92. 62. 77. 70. 52. 56. 130. 82. 19. 71. 128. 143. 115. 127. + 165. 182. 167. 177. 193. 180. 182. 184. 150. 139. 161. 176. 189. + 197. 182. 172. 164. 162. 161. 157. 155. 155. 165. 165. 169. 173. + 175. 176. 181. 187. 194. 195. 197. 198. 198. 200. 203. 206. 203. + 204. 206. 208. 210. 211. 211. 212. 213. 207. 188. 156. 122. 92. 68. + 53. 40. 37. 42. 61. 70. 124. 179. 149. 99. 59. 49. 46. 49. 60. 55. + 56. 60. 58. 58. 60. 64. 62. 55. 49. 50. 52. 53. 58. 54. 41. 52. 86. + 129. 143. 145. 133. 134. 153. 166. 165. 163. 163. 163. 162. 160. + 158. 156. 155. 151. 151. 151. 151. 150. 150. 150. 150. 146. 145. + 146. 146. 147. 149. 150. 151. 152. 152. 153. 153. 154. 155. 155. + 156. 154. 154. 154. 154. 153. 152. 151. 150. 105. 104. 103. 102. + 101. 99. 98. 98. 96. 95. 92. 89. 91. 103. 121. 136. 148. 156. 165. + 171. 173. 173. 174. 176. 177. 173. 174. 170. 157. 148. 135. 114. 93. + 78. 77. 83. 84. 91. 97. 94. 99. 100. 100. 101. 102. 103. 103. 104. + 105. 102. 100. 102. 104. 106. 114. 123. 113. 115. 118. 119. 119. + 117. 117. 118. 122. 109. 123. 114. 150. 189. 114. 121. 114. 124. + 134. 137. 133. 129. 128. 130. 115. 83. 54. 56. 56. 53. 98. 82. 35. + 49. 49. 33. 65. 82. 74. 41. 58. 72. 60. 45. 51. 51. 49. 64. 60. 69. + 45. 50. 66. 51. 83. 49. 33. 33. 89. 98. 64. 125. 142. 117. 126. 168. + 170. 155. 174. 188. 183. 188. 190. 179. 140. 129. 166. 193. 189. + 184. 165. 160. 158. 158. 156. 155. 159. 166. 170. 168. 168. 171. + 175. 180. 184. 186. 193. 195. 198. 199. 199. 200. 202. 204. 202. + 204. 205. 207. 209. 210. 211. 211. 215. 212. 196. 165. 131. 102. 78. + 64. 46. 38. 45. 52. 80. 103. 179. 160. 99. 58. 48. 47. 50. 59. 56. + 60. 58. 58. 59. 60. 60. 57. 53. 49. 47. 54. 56. 53. 46. 41. 64. 105. + 138. 141. 138. 134. 141. 157. 165. 164. 164. 163. 163. 162. 161. + 160. 160. 160. 157. 157. 156. 155. 154. 153. 152. 152. 147. 146. + 145. 144. 144. 144. 145. 145. 146. 147. 148. 149. 151. 152. 153. + 154. 153. 153. 153. 153. 153. 152. 151. 150. 102. 103. 103. 103. + 102. 100. 98. 97. 97. 96. 94. 90. 92. 104. 123. 138. 148. 156. 165. + 171. 173. 173. 174. 176. 177. 173. 174. 170. 157. 148. 135. 114. 92. + 77. 76. 83. 84. 90. 96. 93. 101. 101. 101. 102. 103. 104. 105. 105. + 107. 103. 101. 102. 104. 106. 113. 121. 115. 116. 116. 116. 116. + 115. 114. 111. 114. 111. 132. 121. 110. 149. 112. 112. 125. 133. + 136. 132. 131. 131. 124. 114. 91. 61. 50. 54. 41. 36. 94. 59. 45. + 56. 50. 46. 43. 59. 58. 57. 79. 73. 48. 43. 57. 46. 46. 80. 49. 69. + 56. 52. 50. 50. 102. 49. 32. 34. 57. 103. 120. 139. 129. 125. 157. + 178. 162. 147. 171. 185. 181. 190. 187. 181. 152. 137. 170. 195. + 180. 171. 154. 152. 153. 157. 157. 156. 160. 166. 171. 172. 172. + 173. 176. 181. 184. 184. 190. 193. 197. 198. 198. 198. 199. 200. + 202. 203. 205. 207. 208. 209. 210. 210. 213. 213. 201. 174. 141. + 110. 86. 70. 48. 43. 41. 49. 83. 89. 170. 172. 103. 62. 53. 51. 51. + 57. 54. 61. 59. 61. 63. 61. 57. 52. 50. 49. 46. 57. 55. 46. 43. 51. + 82. 123. 142. 136. 132. 138. 150. 160. 164. 164. 163. 162. 161. 160. + 160. 161. 162. 163. 162. 161. 160. 159. 157. 156. 155. 154. 148. + 148. 146. 145. 144. 144. 144. 145. 143. 143. 144. 145. 146. 147. + 148. 149. 152. 153. 153. 153. 153. 152. 151. 150. 100. 102. 103. + 104. 103. 101. 98. 96. 99. 98. 95. 92. 94. 106. 125. 139. 148. 156. + 165. 171. 173. 173. 174. 176. 177. 173. 174. 170. 157. 148. 135. + 114. 91. 77. 76. 83. 84. 90. 96. 92. 103. 103. 103. 103. 104. 105. + 106. 107. 105. 102. 103. 106. 107. 105. 107. 111. 117. 116. 114. + 113. 113. 113. 110. 106. 107. 114. 132. 131. 86. 110. 110. 105. 132. + 137. 133. 125. 126. 131. 118. 98. 66. 55. 70. 77. 44. 33. 105. 67. + 57. 59. 47. 59. 32. 45. 61. 100. 94. 67. 33. 40. 61. 42. 43. 93. 44. + 60. 57. 61. 50. 50. 116. 63. 25. 34. 31. 88. 144. 118. 111. 159. + 178. 153. 157. 164. 156. 171. 193. 186. 177. 188. 176. 153. 169. + 182. 166. 164. 159. 156. 158. 163. 165. 163. 162. 164. 172. 176. + 178. 177. 176. 178. 180. 180. 187. 191. 195. 197. 197. 197. 197. + 197. 201. 202. 204. 206. 207. 209. 209. 209. 208. 211. 203. 179. + 146. 115. 88. 71. 42. 43. 30. 45. 77. 78. 155. 174. 108. 68. 58. 55. + 51. 55. 51. 59. 60. 64. 67. 63. 55. 49. 47. 48. 48. 59. 54. 42. 45. + 62. 97. 135. 145. 132. 129. 141. 156. 162. 163. 164. 161. 160. 158. + 157. 158. 160. 162. 164. 164. 163. 162. 160. 159. 157. 156. 155. + 150. 149. 148. 147. 146. 146. 146. 146. 142. 143. 143. 143. 144. + 144. 144. 144. 152. 152. 153. 153. 153. 152. 151. 151. 102. 102. + 102. 101. 100. 99. 98. 97. 95. 96. 94. 90. 90. 103. 123. 140. 150. + 155. 163. 169. 172. 174. 176. 177. 176. 172. 175. 171. 158. 148. + 134. 113. 91. 79. 73. 79. 84. 86. 91. 98. 98. 100. 102. 103. 103. + 102. 103. 105. 101. 102. 104. 104. 105. 107. 111. 114. 113. 118. + 125. 119. 114. 124. 129. 117. 129. 112. 150. 101. 114. 145. 167. + 117. 117. 126. 125. 134. 122. 119. 132. 100. 53. 60. 107. 53. 34. + 38. 92. 86. 58. 43. 55. 46. 63. 77. 102. 80. 73. 47. 37. 51. 53. 43. + 58. 88. 37. 56. 113. 50. 48. 78. 64. 43. 38. 45. 72. 124. 107. 92. + 152. 176. 158. 167. 164. 151. 156. 178. 191. 187. 167. 204. 176. + 161. 176. 171. 168. 155. 149. 161. 169. 165. 162. 166. 170. 171. + 175. 173. 176. 181. 177. 169. 173. 184. 185. 188. 192. 196. 198. + 197. 196. 195. 200. 200. 202. 204. 207. 210. 212. 212. 207. 211. + 208. 187. 154. 119. 91. 76. 47. 42. 45. 38. 63. 79. 144. 178. 131. + 57. 71. 52. 63. 65. 56. 63. 56. 66. 69. 60. 51. 51. 55. 56. 53. 53. + 49. 44. 47. 70. 108. 139. 142. 130. 129. 143. 155. 157. 160. 166. + 162. 162. 162. 161. 161. 161. 160. 160. 164. 165. 165. 165. 163. + 161. 158. 157. 156. 155. 153. 151. 148. 146. 144. 143. 142. 142. + 143. 144. 144. 143. 142. 142. 146. 146. 147. 148. 149. 150. 151. + 151. 102. 102. 102. 101. 100. 99. 98. 97. 97. 97. 95. 90. 91. 102. + 123. 139. 150. 155. 163. 169. 172. 174. 176. 177. 176. 172. 175. + 171. 158. 148. 135. 113. 90. 79. 73. 80. 85. 86. 90. 98. 98. 100. + 102. 103. 102. 102. 103. 105. 102. 103. 104. 104. 105. 107. 111. + 114. 116. 113. 114. 121. 125. 121. 119. 124. 120. 132. 167. 101. + 124. 157. 163. 132. 120. 133. 127. 133. 127. 115. 106. 66. 54. 69. + 99. 47. 34. 47. 107. 88. 41. 37. 53. 50. 72. 78. 91. 75. 57. 46. 41. + 45. 47. 47. 54. 66. 33. 54. 91. 53. 51. 85. 60. 53. 45. 42. 138. + 139. 83. 146. 193. 158. 172. 180. 174. 158. 157. 174. 186. 185. 194. + 192. 175. 198. 191. 131. 115. 129. 140. 150. 158. 159. 161. 167. + 169. 167. 173. 173. 177. 181. 181. 178. 180. 184. 184. 187. 191. + 195. 196. 196. 194. 193. 195. 199. 203. 205. 205. 206. 209. 211. + 214. 216. 211. 190. 154. 112. 75. 53. 46. 40. 43. 39. 62. 74. 136. + 180. 137. 70. 68. 53. 63. 62. 58. 59. 62. 69. 70. 60. 50. 48. 51. + 51. 50. 52. 49. 45. 54. 83. 118. 140. 138. 130. 132. 146. 158. 159. + 160. 165. 162. 162. 161. 161. 160. 160. 160. 160. 163. 164. 164. + 164. 163. 160. 158. 157. 156. 155. 154. 152. 150. 148. 146. 146. + 144. 144. 145. 145. 144. 143. 142. 142. 142. 142. 143. 144. 144. + 145. 145. 146. 101. 102. 102. 102. 101. 100. 98. 98. 100. 99. 97. + 91. 91. 102. 122. 138. 149. 155. 163. 169. 173. 174. 176. 177. 176. + 173. 175. 171. 158. 149. 135. 114. 89. 78. 74. 81. 87. 87. 90. 97. + 98. 100. 103. 103. 102. 102. 103. 104. 102. 103. 104. 105. 105. 108. + 111. 115. 116. 115. 112. 123. 130. 112. 118. 159. 193. 149. 128. 49. + 55. 55. 72. 124. 128. 140. 122. 115. 121. 112. 92. 59. 67. 87. 85. + 38. 38. 59. 121. 81. 37. 42. 50. 47. 67. 62. 61. 56. 42. 47. 47. 43. + 46. 56. 60. 56. 39. 67. 92. 50. 66. 78. 52. 40. 48. 100. 147. 111. + 118. 184. 182. 160. 178. 181. 173. 158. 158. 175. 190. 193. 191. + 191. 173. 156. 118. 78. 84. 97. 122. 126. 131. 135. 145. 158. 169. + 172. 176. 179. 179. 176. 176. 179. 179. 176. 182. 185. 189. 193. + 195. 194. 192. 190. 196. 198. 200. 200. 199. 200. 204. 208. 202. + 198. 189. 171. 142. 106. 71. 50. 45. 37. 41. 41. 59. 67. 122. 183. + 145. 89. 63. 54. 64. 60. 62. 55. 65. 69. 68. 59. 50. 48. 49. 50. 49. + 53. 49. 46. 64. 101. 131. 141. 133. 130. 136. 152. 161. 160. 159. + 162. 161. 161. 160. 160. 160. 159. 159. 159. 162. 162. 163. 163. + 162. 160. 158. 156. 155. 155. 154. 153. 152. 151. 150. 149. 148. + 148. 147. 147. 146. 144. 143. 142. 140. 140. 140. 140. 140. 140. + 140. 140. 101. 102. 102. 102. 101. 100. 99. 99. 101. 101. 98. 92. + 91. 102. 121. 137. 149. 155. 163. 170. 173. 175. 175. 176. 177. 173. + 176. 172. 158. 149. 135. 114. 88. 78. 75. 83. 88. 88. 90. 96. 99. + 101. 103. 103. 102. 102. 103. 104. 102. 103. 104. 105. 105. 107. + 111. 115. 113. 125. 120. 120. 124. 108. 129. 195. 160. 85. 68. 33. + 37. 27. 60. 143. 176. 173. 130. 95. 93. 84. 62. 48. 88. 101. 66. 32. + 49. 74. 126. 69. 42. 50. 46. 46. 61. 51. 45. 56. 40. 48. 51. 46. 49. + 60. 70. 72. 45. 76. 96. 44. 75. 53. 44. 32. 86. 151. 103. 102. 175. + 177. 162. 174. 187. 178. 162. 151. 159. 179. 194. 197. 198. 192. + 160. 114. 86. 99. 117. 107. 103. 100. 95. 93. 101. 119. 140. 153. + 171. 181. 183. 176. 172. 176. 176. 171. 179. 182. 187. 191. 193. + 192. 189. 187. 195. 194. 195. 197. 201. 205. 208. 209. 210. 192. + 169. 145. 119. 88. 60. 44. 46. 37. 40. 43. 55. 62. 106. 184. 150. + 105. 59. 54. 64. 61. 66. 55. 64. 65. 62. 56. 51. 49. 51. 53. 52. 55. + 49. 46. 72. 116. 140. 140. 129. 131. 142. 157. 164. 162. 159. 159. + 160. 160. 159. 159. 158. 158. 158. 158. 160. 160. 161. 162. 161. + 159. 158. 156. 155. 155. 154. 154. 154. 153. 153. 153. 151. 151. + 151. 149. 148. 146. 144. 143. 141. 141. 140. 140. 139. 138. 138. + 137. 101. 102. 102. 102. 102. 101. 100. 100. 101. 101. 98. 92. 90. + 101. 120. 136. 148. 155. 163. 171. 174. 175. 175. 175. 177. 174. + 176. 172. 159. 150. 136. 115. 89. 79. 76. 83. 89. 88. 90. 96. 99. + 101. 103. 103. 102. 101. 102. 103. 101. 102. 103. 104. 104. 107. + 111. 114. 110. 127. 119. 114. 124. 120. 136. 184. 143. 77. 68. 50. + 40. 57. 111. 152. 169. 158. 120. 81. 76. 70. 55. 61. 95. 92. 45. 36. + 67. 87. 122. 72. 35. 45. 44. 58. 69. 61. 55. 78. 54. 50. 47. 47. 46. + 50. 67. 86. 60. 78. 66. 60. 62. 33. 38. 71. 144. 123. 106. 154. 175. + 164. 184. 180. 202. 180. 156. 152. 168. 188. 195. 192. 194. 148. + 126. 133. 144. 149. 142. 136. 114. 106. 91. 77. 68. 72. 86. 100. + 130. 152. 171. 176. 176. 179. 178. 173. 176. 179. 185. 190. 192. + 191. 188. 186. 189. 189. 193. 200. 206. 204. 193. 183. 155. 135. + 115. 104. 93. 77. 61. 53. 49. 40. 41. 43. 51. 61. 92. 182. 153. 116. + 60. 52. 62. 66. 66. 59. 66. 63. 58. 54. 51. 49. 51. 54. 57. 56. 48. + 49. 80. 125. 143. 136. 128. 134. 148. 160. 165. 162. 158. 158. 158. + 158. 158. 158. 157. 157. 156. 156. 157. 158. 159. 160. 160. 159. + 157. 156. 154. 154. 155. 155. 155. 155. 155. 155. 154. 154. 153. + 152. 150. 148. 146. 144. 142. 142. 140. 139. 137. 136. 134. 134. + 101. 101. 102. 102. 102. 102. 101. 101. 100. 100. 96. 91. 89. 100. + 120. 136. 148. 154. 164. 171. 174. 175. 175. 175. 178. 174. 176. + 173. 159. 150. 136. 115. 90. 79. 76. 83. 88. 88. 91. 98. 100. 102. + 104. 104. 102. 101. 102. 103. 100. 101. 102. 102. 103. 105. 109. + 112. 110. 118. 111. 115. 138. 142. 136. 142. 181. 104. 60. 54. 24. + 28. 102. 131. 119. 102. 91. 75. 73. 74. 68. 87. 85. 70. 38. 54. 82. + 85. 106. 94. 32. 38. 46. 73. 70. 60. 53. 77. 76. 55. 41. 42. 39. 36. + 52. 76. 89. 93. 38. 88. 41. 31. 47. 125. 149. 101. 156. 183. 158. + 175. 188. 191. 198. 173. 154. 162. 186. 199. 192. 180. 143. 117. + 125. 149. 162. 151. 137. 156. 156. 143. 125. 104. 84. 68. 64. 67. + 76. 103. 137. 161. 173. 177. 174. 170. 172. 177. 183. 190. 192. 192. + 189. 187. 190. 191. 192. 193. 186. 166. 140. 120. 94. 84. 82. 93. + 102. 98. 91. 88. 53. 47. 44. 41. 48. 65. 82. 177. 154. 121. 67. 51. + 57. 74. 61. 64. 71. 63. 55. 52. 50. 48. 48. 51. 59. 55. 49. 58. 92. + 130. 142. 133. 129. 139. 153. 162. 164. 161. 158. 157. 157. 157. + 157. 156. 156. 156. 155. 155. 155. 156. 158. 159. 159. 158. 157. + 156. 154. 154. 155. 155. 155. 155. 155. 155. 156. 156. 155. 154. + 152. 150. 148. 147. 143. 142. 140. 138. 135. 133. 131. 130. 101. + 101. 102. 103. 103. 102. 102. 101. 98. 98. 95. 89. 88. 99. 119. 135. + 147. 154. 164. 172. 175. 175. 175. 174. 178. 174. 177. 173. 159. + 150. 136. 115. 92. 80. 75. 81. 87. 88. 92. 99. 100. 102. 104. 104. + 102. 101. 101. 102. 98. 99. 101. 101. 101. 104. 108. 111. 111. 109. + 113. 131. 151. 154. 142. 131. 140. 105. 58. 93. 77. 44. 105. 127. + 128. 88. 82. 73. 62. 63. 66. 92. 76. 57. 54. 83. 87. 61. 71. 112. + 45. 40. 48. 80. 56. 45. 42. 63. 94. 64. 39. 37. 40. 37. 43. 54. 79. + 97. 45. 76. 32. 43. 91. 140. 123. 140. 181. 172. 168. 185. 179. 201. + 183. 165. 158. 176. 195. 190. 163. 140. 110. 122. 140. 133. 134. + 129. 116. 147. 166. 149. 131. 120. 110. 97. 86. 82. 73. 85. 110. + 139. 159. 165. 165. 165. 169. 174. 182. 189. 193. 193. 190. 188. + 192. 190. 183. 170. 148. 124. 102. 89. 114. 104. 104. 116. 120. 110. + 97. 93. 57. 55. 48. 39. 45. 70. 76. 172. 156. 123. 77. 49. 51. 80. + 51. 68. 72. 60. 51. 50. 50. 48. 49. 53. 57. 51. 51. 71. 107. 136. + 140. 130. 132. 144. 156. 162. 161. 159. 158. 158. 156. 156. 156. + 156. 155. 155. 154. 154. 153. 154. 156. 158. 158. 158. 157. 156. + 155. 155. 154. 154. 154. 154. 154. 154. 157. 157. 157. 156. 154. + 153. 151. 150. 147. 145. 143. 140. 137. 134. 132. 131. 101. 101. + 102. 103. 103. 103. 102. 102. 96. 96. 93. 88. 88. 99. 119. 135. 147. + 154. 164. 172. 175. 175. 175. 174. 178. 174. 177. 173. 160. 150. + 137. 115. 93. 81. 75. 81. 86. 88. 93. 101. 100. 102. 104. 104. 102. + 101. 101. 102. 97. 98. 100. 100. 100. 103. 107. 110. 112. 107. 124. + 149. 156. 154. 155. 152. 155. 190. 128. 140. 129. 91. 129. 117. 146. + 82. 71. 64. 51. 63. 81. 117. 76. 56. 75. 107. 85. 34. 39. 117. 61. + 45. 49. 80. 45. 38. 43. 67. 104. 72. 42. 37. 46. 49. 44. 40. 32. 76. + 62. 32. 32. 53. 141. 125. 123. 182. 174. 171. 182. 181. 199. 196. + 181. 168. 168. 185. 192. 166. 121. 88. 110. 105. 108. 103. 119. 106. + 69. 96. 136. 115. 99. 101. 111. 113. 109. 106. 111. 102. 106. 128. + 148. 156. 160. 165. 168. 173. 182. 189. 194. 194. 191. 189. 188. + 184. 171. 149. 126. 111. 109. 113. 105. 94. 92. 100. 101. 88. 76. + 73. 60. 60. 51. 38. 44. 74. 73. 168. 157. 124. 84. 49. 48. 83. 43. + 68. 68. 56. 47. 48. 51. 51. 53. 57. 54. 48. 54. 82. 118. 140. 139. + 129. 135. 146. 158. 162. 159. 157. 157. 158. 156. 156. 155. 155. + 155. 154. 154. 154. 152. 154. 155. 157. 158. 158. 157. 156. 155. + 155. 154. 154. 154. 153. 153. 153. 157. 157. 157. 157. 155. 154. + 152. 151. 151. 150. 147. 144. 141. 137. 135. 134. 99. 102. 103. 100. + 99. 102. 101. 97. 97. 96. 91. 85. 84. 96. 118. 135. 146. 155. 165. + 173. 175. 175. 177. 178. 178. 174. 175. 171. 158. 151. 139. 118. 92. + 77. 75. 81. 83. 90. 97. 95. 99. 100. 102. 104. 104. 102. 100. 99. + 99. 106. 94. 89. 118. 95. 106. 107. 125. 138. 142. 143. 152. 156. + 156. 161. 166. 163. 163. 167. 155. 118. 83. 70. 65. 46. 56. 64. 61. + 92. 114. 88. 63. 78. 76. 114. 60. 37. 34. 80. 90. 36. 46. 87. 47. + 40. 39. 55. 86. 102. 65. 31. 49. 52. 38. 50. 37. 49. 47. 46. 37. + 113. 141. 106. 168. 172. 173. 174. 183. 197. 202. 198. 182. 173. + 193. 198. 145. 94. 84. 89. 81. 103. 72. 50. 72. 60. 40. 67. 84. 54. + 53. 52. 83. 120. 113. 119. 121. 119. 120. 127. 138. 149. 156. 159. + 155. 176. 180. 184. 203. 201. 189. 192. 190. 173. 173. 136. 129. + 119. 66. 79. 60. 52. 50. 59. 66. 66. 65. 67. 70. 55. 44. 32. 47. 75. + 71. 168. 168. 111. 98. 58. 50. 70. 57. 66. 64. 56. 49. 49. 49. 49. + 52. 56. 51. 40. 55. 100. 136. 142. 134. 130. 141. 151. 159. 161. + 159. 159. 156. 152. 155. 155. 155. 155. 155. 155. 155. 155. 155. + 156. 156. 157. 157. 156. 156. 155. 152. 152. 152. 152. 153. 154. + 155. 156. 156. 157. 157. 157. 155. 151. 148. 146. 146. 146. 145. + 143. 141. 139. 137. 136. 97. 101. 101. 98. 98. 100. 99. 96. 96. 94. + 90. 83. 83. 95. 117. 134. 146. 155. 165. 173. 175. 175. 177. 178. + 178. 174. 175. 171. 158. 150. 138. 118. 93. 78. 75. 81. 81. 87. 94. + 92. 98. 99. 101. 102. 102. 101. 99. 98. 102. 95. 90. 95. 104. 84. + 111. 156. 149. 156. 152. 139. 143. 159. 155. 134. 144. 143. 119. + 119. 136. 97. 39. 28. 28. 45. 88. 93. 75. 108. 123. 71. 65. 81. 86. + 118. 61. 39. 38. 83. 65. 52. 49. 100. 38. 45. 33. 39. 59. 106. 98. + 52. 38. 40. 39. 46. 42. 34. 43. 23. 78. 137. 123. 134. 183. 179. + 177. 180. 191. 199. 197. 191. 186. 187. 184. 145. 90. 73. 77. 68. + 62. 50. 55. 59. 50. 54. 58. 43. 52. 38. 45. 48. 50. 65. 101. 152. + 128. 125. 124. 127. 135. 144. 151. 154. 160. 172. 182. 190. 197. + 193. 193. 202. 193. 189. 124. 87. 73. 62. 69. 45. 45. 46. 52. 59. + 60. 57. 60. 66. 61. 50. 44. 34. 47. 72. 65. 161. 171. 116. 98. 63. + 54. 73. 59. 67. 62. 54. 48. 49. 49. 49. 52. 56. 48. 39. 58. 105. + 138. 139. 131. 131. 145. 154. 160. 160. 158. 158. 156. 153. 155. + 155. 155. 155. 155. 155. 155. 155. 155. 155. 156. 157. 157. 156. + 155. 155. 152. 152. 152. 153. 153. 153. 153. 153. 154. 155. 155. + 154. 152. 149. 146. 144. 145. 145. 144. 143. 140. 138. 135. 134. 96. + 99. 99. 96. 96. 98. 97. 93. 94. 92. 87. 81. 80. 93. 115. 133. 146. + 155. 165. 173. 175. 175. 177. 178. 178. 173. 175. 170. 157. 149. + 137. 117. 93. 78. 75. 80. 80. 85. 92. 89. 97. 98. 99. 100. 100. 99. + 98. 97. 89. 102. 105. 93. 87. 118. 143. 172. 221. 150. 126. 152. + 156. 143. 153. 169. 150. 141. 83. 61. 92. 71. 31. 46. 47. 97. 91. + 72. 98. 101. 78. 83. 73. 86. 98. 119. 60. 41. 42. 82. 46. 75. 53. + 114. 37. 53. 37. 35. 40. 75. 108. 108. 76. 42. 36. 50. 48. 34. 34. + 47. 137. 136. 130. 182. 181. 171. 168. 180. 195. 200. 195. 188. 199. + 183. 148. 93. 54. 56. 62. 47. 45. 51. 47. 44. 48. 48. 50. 61. 96. + 83. 58. 45. 29. 29. 72. 109. 134. 131. 128. 129. 134. 141. 147. 150. + 163. 167. 184. 197. 195. 196. 204. 207. 178. 113. 83. 60. 48. 49. + 44. 65. 66. 57. 49. 49. 52. 55. 57. 60. 50. 45. 46. 38. 48. 68. 58. + 153. 172. 119. 95. 68. 57. 75. 60. 66. 58. 51. 47. 48. 50. 49. 51. + 55. 47. 42. 67. 117. 144. 137. 130. 136. 151. 157. 160. 158. 157. + 158. 157. 153. 154. 154. 154. 154. 154. 154. 154. 154. 154. 155. + 156. 156. 156. 156. 155. 154. 152. 152. 153. 154. 154. 152. 151. + 150. 152. 152. 152. 151. 149. 146. 143. 141. 141. 141. 142. 142. + 140. 138. 136. 134. 94. 98. 98. 95. 94. 96. 95. 91. 92. 90. 85. 78. + 78. 91. 114. 132. 146. 155. 165. 173. 175. 175. 177. 178. 178. 173. + 175. 170. 157. 148. 136. 116. 91. 76. 73. 79. 79. 86. 92. 90. 96. + 97. 98. 99. 99. 98. 97. 96. 91. 101. 98. 83. 83. 162. 184. 188. 179. + 135. 129. 149. 153. 159. 149. 114. 127. 120. 80. 55. 62. 45. 27. 44. + 103. 111. 64. 57. 101. 70. 38. 91. 89. 90. 105. 111. 54. 43. 43. 73. + 39. 79. 50. 109. 54. 54. 45. 40. 37. 44. 82. 110. 93. 67. 56. 49. + 34. 32. 21. 102. 148. 99. 153. 192. 176. 167. 167. 182. 196. 199. + 195. 192. 198. 147. 96. 72. 61. 52. 47. 45. 52. 64. 53. 39. 44. 44. + 59. 94. 164. 165. 113. 73. 43. 35. 63. 57. 129. 129. 129. 131. 136. + 141. 145. 148. 159. 163. 185. 199. 200. 212. 211. 186. 118. 40. 54. + 52. 51. 74. 70. 115. 127. 91. 52. 38. 47. 59. 58. 51. 46. 44. 48. + 41. 49. 67. 56. 151. 172. 122. 89. 73. 59. 76. 59. 61. 54. 49. 46. + 49. 51. 50. 50. 53. 49. 52. 83. 131. 151. 138. 133. 145. 157. 160. + 161. 157. 156. 157. 157. 153. 153. 153. 153. 153. 153. 153. 153. + 153. 154. 154. 155. 155. 155. 155. 154. 154. 151. 152. 154. 154. + 153. 151. 148. 147. 151. 150. 150. 149. 147. 144. 142. 140. 136. + 136. 138. 138. 138. 137. 136. 135. 95. 98. 98. 94. 93. 95. 94. 90. + 90. 88. 82. 76. 76. 89. 113. 131. 146. 155. 165. 173. 175. 175. 177. + 178. 179. 174. 175. 171. 157. 149. 136. 116. 89. 74. 72. 79. 81. 88. + 96. 94. 97. 98. 98. 98. 98. 98. 98. 97. 109. 85. 74. 85. 84. 155. + 196. 207. 161. 135. 135. 144. 145. 159. 146. 98. 144. 112. 82. 57. + 38. 41. 57. 61. 102. 55. 53. 84. 75. 46. 49. 70. 108. 92. 107. 98. + 46. 44. 42. 59. 34. 57. 41. 91. 86. 50. 47. 40. 39. 46. 57. 49. 46. + 77. 81. 38. 38. 38. 55. 145. 124. 119. 187. 174. 180. 178. 182. 193. + 201. 201. 196. 194. 156. 107. 68. 66. 66. 47. 41. 57. 77. 50. 60. + 64. 37. 51. 85. 82. 178. 202. 176. 136. 84. 56. 82. 85. 114. 117. + 123. 129. 134. 139. 143. 145. 154. 164. 185. 198. 208. 224. 199. + 138. 58. 56. 40. 45. 46. 74. 126. 121. 170. 126. 72. 43. 45. 55. 55. + 48. 48. 46. 51. 44. 51. 69. 57. 152. 174. 127. 85. 81. 63. 78. 60. + 59. 52. 47. 47. 50. 52. 50. 49. 50. 51. 63. 99. 140. 151. 138. 136. + 150. 160. 162. 160. 155. 155. 157. 156. 153. 153. 153. 153. 153. + 153. 153. 153. 153. 153. 153. 154. 154. 154. 154. 153. 153. 151. + 152. 153. 154. 153. 150. 147. 145. 150. 150. 149. 147. 145. 143. + 141. 140. 133. 133. 133. 133. 132. 132. 131. 131. 96. 99. 99. 95. + 94. 96. 94. 90. 89. 87. 81. 74. 74. 88. 112. 131. 146. 155. 165. + 173. 175. 175. 177. 178. 181. 176. 177. 172. 158. 149. 137. 116. 90. + 75. 74. 81. 83. 91. 99. 97. 100. 100. 100. 100. 100. 100. 100. 100. + 97. 94. 89. 92. 72. 122. 178. 156. 178. 147. 141. 152. 148. 145. + 143. 130. 150. 92. 58. 42. 33. 65. 100. 93. 56. 47. 61. 77. 61. 40. + 51. 73. 119. 92. 111. 89. 41. 46. 43. 49. 37. 40. 42. 76. 115. 56. + 46. 41. 46. 45. 48. 37. 30. 53. 62. 36. 51. 50. 107. 137. 104. 178. + 193. 151. 169. 179. 190. 198. 203. 202. 192. 181. 106. 97. 79. 68. + 60. 44. 45. 67. 98. 81. 73. 74. 71. 69. 70. 71. 192. 202. 202. 189. + 135. 81. 89. 116. 102. 107. 115. 122. 129. 134. 139. 143. 153. 170. + 188. 199. 214. 218. 168. 97. 68. 62. 68. 64. 57. 70. 93. 112. 171. + 142. 97. 59. 44. 45. 49. 49. 50. 47. 51. 45. 54. 71. 58. 150. 179. + 134. 83. 91. 69. 83. 63. 59. 51. 48. 48. 53. 54. 50. 48. 48. 50. 75. + 114. 142. 145. 135. 139. 152. 160. 161. 158. 154. 154. 157. 156. + 151. 152. 152. 152. 152. 152. 152. 152. 152. 152. 152. 153. 154. + 154. 153. 152. 152. 151. 151. 152. 152. 151. 149. 147. 146. 149. + 148. 147. 145. 143. 141. 139. 139. 133. 132. 130. 129. 129. 130. + 131. 132. 98. 101. 101. 97. 96. 97. 95. 91. 89. 86. 80. 73. 74. 88. + 113. 132. 146. 155. 165. 173. 175. 175. 177. 178. 182. 177. 178. + 173. 159. 150. 138. 117. 94. 79. 77. 84. 85. 93. 101. 98. 102. 102. + 102. 101. 101. 102. 102. 102. 90. 104. 95. 80. 53. 88. 164. 100. + 128. 170. 191. 172. 154. 146. 111. 63. 71. 44. 33. 45. 63. 84. 84. + 62. 39. 78. 67. 52. 67. 53. 50. 98. 120. 91. 121. 91. 41. 49. 46. + 46. 51. 42. 45. 58. 114. 64. 44. 50. 49. 39. 48. 59. 47. 33. 36. 43. + 43. 68. 114. 99. 117. 181. 162. 147. 164. 181. 193. 196. 198. 194. + 169. 139. 99. 112. 106. 93. 83. 61. 51. 67. 102. 121. 89. 69. 91. + 76. 70. 121. 214. 199. 207. 202. 162. 111. 89. 113. 103. 108. 113. + 119. 124. 131. 139. 145. 156. 176. 192. 207. 221. 200. 140. 90. 113. + 67. 95. 87. 82. 80. 62. 139. 165. 143. 104. 65. 44. 43. 47. 47. 48. + 44. 48. 45. 56. 73. 55. 143. 180. 138. 80. 96. 72. 85. 63. 58. 52. + 49. 50. 55. 56. 51. 47. 46. 53. 88. 128. 144. 139. 135. 144. 155. + 159. 159. 156. 153. 154. 157. 155. 150. 151. 151. 151. 151. 151. + 151. 151. 151. 151. 152. 153. 153. 153. 153. 152. 151. 151. 151. + 150. 150. 149. 148. 148. 148. 147. 146. 144. 141. 139. 138. 137. + 136. 132. 131. 130. 131. 135. 141. 147. 151. 99. 102. 102. 98. 97. + 98. 96. 92. 89. 86. 80. 73. 73. 88. 113. 132. 146. 155. 165. 173. + 175. 175. 177. 178. 183. 178. 179. 174. 160. 151. 138. 118. 97. 82. + 80. 86. 87. 93. 100. 98. 104. 104. 103. 103. 103. 103. 104. 104. + 115. 89. 56. 59. 43. 56. 163. 115. 159. 190. 215. 214. 178. 114. 59. + 41. 44. 45. 35. 46. 78. 84. 66. 57. 56. 68. 67. 67. 73. 70. 78. 105. + 117. 90. 130. 95. 44. 51. 50. 48. 62. 48. 42. 36. 92. 63. 38. 56. + 42. 48. 52. 47. 39. 38. 42. 44. 47. 109. 111. 97. 168. 161. 153. + 181. 180. 197. 205. 199. 194. 181. 138. 91. 123. 128. 123. 126. 123. + 85. 54. 62. 100. 106. 98. 77. 59. 67. 120. 184. 205. 197. 217. 196. + 161. 132. 102. 118. 112. 114. 117. 119. 123. 131. 141. 149. 158. + 179. 196. 217. 227. 187. 128. 103. 131. 119. 87. 84. 88. 82. 119. + 173. 172. 142. 96. 58. 45. 49. 49. 43. 45. 41. 46. 45. 58. 74. 52. + 137. 179. 138. 76. 97. 71. 84. 61. 54. 52. 50. 51. 56. 57. 51. 46. + 45. 56. 99. 138. 146. 137. 138. 149. 159. 158. 158. 155. 153. 154. + 157. 155. 149. 151. 151. 151. 151. 151. 151. 151. 151. 151. 152. + 152. 153. 153. 152. 152. 151. 151. 150. 149. 148. 148. 148. 149. + 149. 145. 143. 141. 139. 137. 135. 135. 134. 129. 129. 131. 136. + 145. 156. 167. 174. 102. 100. 98. 98. 98. 97. 95. 93. 91. 88. 81. + 73. 72. 87. 112. 132. 145. 157. 168. 172. 174. 178. 180. 178. 179. + 180. 177. 170. 162. 151. 133. 118. 101. 83. 81. 90. 92. 96. 104. + 105. 107. 107. 104. 112. 109. 104. 101. 77. 76. 51. 68. 63. 93. 119. + 150. 162. 171. 201. 233. 214. 151. 41. 67. 46. 41. 31. 49. 82. 93. + 87. 77. 67. 43. 66. 84. 94. 75. 102. 67. 121. 91. 87. 121. 107. 53. + 51. 54. 32. 55. 47. 44. 49. 53. 52. 53. 57. 49. 35. 49. 58. 38. 34. + 46. 39. 90. 143. 94. 154. 183. 155. 170. 183. 198. 193. 191. 200. + 182. 122. 99. 133. 118. 125. 135. 140. 134. 117. 94. 79. 104. 111. + 124. 125. 118. 138. 179. 205. 205. 201. 198. 181. 153. 139. 132. + 120. 135. 121. 114. 122. 129. 129. 133. 142. 158. 177. 200. 221. + 222. 179. 119. 86. 122. 128. 126. 105. 101. 138. 174. 178. 174. 135. + 92. 55. 52. 56. 45. 58. 47. 41. 52. 52. 69. 66. 57. 120. 171. 164. + 88. 80. 98. 71. 66. 54. 45. 53. 48. 44. 53. 53. 44. 41. 66. 112. + 140. 138. 136. 141. 150. 161. 156. 156. 155. 154. 154. 153. 152. + 152. 150. 149. 150. 154. 157. 158. 155. 151. 152. 152. 153. 153. + 153. 152. 151. 151. 148. 152. 151. 146. 145. 148. 145. 138. 137. + 141. 143. 141. 135. 130. 128. 128. 135. 143. 154. 161. 165. 169. + 176. 181. 103. 101. 100. 100. 100. 98. 95. 93. 90. 88. 82. 73. 73. + 87. 112. 132. 145. 156. 167. 172. 175. 178. 180. 179. 180. 181. 178. + 171. 163. 152. 134. 119. 101. 83. 81. 90. 92. 96. 104. 104. 110. + 109. 110. 110. 113. 101. 68. 43. 37. 58. 115. 131. 145. 163. 176. + 181. 180. 203. 169. 77. 49. 63. 104. 42. 58. 71. 101. 122. 114. 87. + 55. 29. 46. 86. 63. 81. 73. 89. 81. 113. 128. 53. 154. 116. 91. 45. + 75. 41. 46. 40. 39. 45. 50. 50. 51. 55. 45. 48. 58. 41. 33. 37. 36. + 58. 135. 113. 132. 187. 165. 160. 189. 180. 202. 196. 203. 173. 116. + 113. 134. 119. 125. 130. 138. 144. 143. 133. 119. 109. 105. 111. + 129. 139. 137. 147. 165. 171. 187. 185. 187. 180. 161. 148. 136. + 117. 131. 121. 117. 124. 128. 128. 132. 141. 158. 178. 200. 218. + 219. 185. 142. 124. 113. 127. 140. 138. 141. 164. 174. 159. 133. + 103. 77. 57. 64. 68. 51. 58. 51. 45. 55. 54. 71. 67. 57. 119. 170. + 166. 93. 81. 96. 71. 64. 52. 46. 49. 45. 46. 55. 53. 50. 56. 80. + 119. 140. 136. 137. 144. 153. 163. 156. 156. 155. 154. 153. 153. + 152. 152. 152. 152. 152. 155. 159. 159. 156. 153. 152. 152. 152. + 153. 152. 152. 151. 150. 147. 150. 148. 143. 142. 146. 145. 140. + 139. 140. 139. 136. 133. 133. 138. 143. 154. 161. 170. 176. 178. + 181. 187. 191. 103. 102. 101. 102. 102. 99. 95. 91. 88. 87. 82. 74. + 73. 86. 111. 131. 145. 156. 167. 172. 175. 178. 180. 179. 181. 182. + 180. 173. 165. 153. 136. 120. 101. 82. 81. 90. 92. 96. 103. 104. + 112. 110. 118. 108. 120. 108. 46. 30. 77. 104. 147. 153. 134. 147. + 147. 156. 178. 118. 70. 45. 41. 46. 84. 104. 102. 89. 84. 87. 76. + 53. 39. 38. 52. 104. 47. 83. 81. 62. 83. 112. 139. 82. 155. 100. 85. + 85. 76. 42. 43. 40. 40. 44. 48. 47. 47. 49. 46. 55. 55. 33. 35. 34. + 39. 101. 142. 92. 163. 196. 165. 171. 194. 192. 201. 210. 175. 114. + 95. 116. 131. 128. 133. 136. 140. 145. 147. 145. 139. 134. 120. 110. + 111. 114. 114. 125. 136. 134. 127. 132. 150. 165. 169. 172. 164. + 145. 127. 121. 122. 127. 128. 126. 131. 140. 153. 177. 202. 219. + 219. 192. 162. 154. 149. 149. 148. 137. 130. 137. 130. 104. 89. 74. + 67. 64. 78. 79. 54. 55. 51. 45. 56. 55. 71. 66. 54. 116. 169. 168. + 103. 83. 93. 69. 59. 50. 48. 45. 42. 51. 59. 52. 54. 74. 101. 128. + 139. 134. 139. 149. 156. 164. 156. 155. 155. 154. 153. 152. 152. + 152. 152. 152. 153. 155. 157. 157. 155. 153. 151. 152. 152. 152. + 151. 150. 149. 149. 146. 147. 145. 140. 139. 142. 143. 141. 138. + 137. 136. 133. 134. 142. 154. 164. 170. 175. 182. 185. 185. 186. + 190. 193. 103. 102. 102. 103. 102. 99. 93. 89. 85. 86. 82. 74. 71. + 84. 109. 130. 144. 156. 167. 172. 175. 179. 181. 179. 183. 184. 181. + 174. 166. 155. 137. 122. 100. 82. 80. 90. 91. 95. 103. 104. 110. + 109. 121. 103. 126. 128. 66. 73. 132. 138. 154. 160. 126. 135. 123. + 137. 111. 70. 56. 58. 48. 46. 67. 115. 111. 83. 73. 93. 95. 59. 32. + 38. 55. 100. 51. 96. 96. 50. 70. 111. 117. 127. 133. 90. 106. 111. + 50. 38. 48. 47. 47. 48. 48. 46. 45. 45. 52. 51. 37. 40. 38. 28. 72. + 139. 111. 115. 172. 170. 183. 176. 179. 205. 202. 177. 116. 88. 114. + 125. 122. 141. 139. 139. 141. 143. 145. 145. 142. 139. 154. 133. + 119. 112. 111. 123. 134. 132. 120. 125. 142. 156. 159. 161. 154. + 136. 124. 124. 127. 131. 128. 125. 129. 138. 147. 173. 201. 222. + 224. 197. 167. 158. 150. 141. 132. 119. 111. 118. 115. 95. 76. 71. + 78. 78. 87. 81. 53. 53. 46. 41. 53. 53. 69. 64. 51. 112. 168. 171. + 114. 85. 89. 68. 55. 49. 50. 43. 43. 57. 62. 47. 53. 85. 119. 135. + 136. 131. 141. 152. 157. 162. 155. 155. 154. 154. 153. 152. 151. + 151. 149. 150. 151. 152. 153. 153. 152. 151. 151. 151. 151. 151. + 150. 149. 148. 147. 144. 145. 145. 141. 139. 138. 137. 137. 131. + 134. 138. 141. 147. 158. 171. 181. 180. 183. 187. 187. 186. 186. + 187. 189. 102. 102. 101. 101. 100. 96. 91. 86. 83. 84. 81. 72. 68. + 81. 107. 129. 144. 155. 167. 172. 175. 179. 181. 180. 184. 185. 182. + 175. 167. 156. 138. 123. 100. 82. 80. 89. 91. 95. 103. 103. 110. + 109. 119. 98. 123. 142. 107. 135. 132. 126. 139. 149. 106. 90. 64. + 79. 84. 71. 61. 47. 39. 44. 48. 73. 137. 124. 108. 111. 113. 85. 61. + 66. 45. 81. 62. 87. 99. 78. 71. 94. 98. 119. 124. 117. 150. 80. 46. + 47. 47. 49. 50. 49. 47. 47. 46. 45. 49. 53. 28. 41. 31. 40. 122. + 139. 104. 157. 174. 155. 186. 178. 190. 203. 179. 106. 84. 110. 118. + 126. 140. 136. 144. 144. 144. 146. 147. 146. 143. 141. 154. 142. + 139. 138. 134. 137. 140. 133. 142. 144. 155. 158. 150. 149. 146. + 132. 125. 128. 133. 134. 129. 125. 128. 135. 147. 170. 195. 218. + 227. 203. 171. 160. 143. 139. 140. 136. 127. 128. 124. 108. 89. 90. + 99. 94. 93. 81. 54. 59. 44. 39. 53. 53. 70. 64. 50. 111. 166. 174. + 125. 86. 83. 66. 51. 50. 50. 44. 46. 61. 61. 41. 50. 89. 131. 139. + 133. 129. 143. 154. 156. 159. 155. 155. 154. 153. 152. 152. 151. + 151. 149. 150. 151. 151. 151. 151. 151. 151. 150. 150. 150. 150. + 149. 147. 146. 145. 143. 144. 145. 144. 139. 134. 131. 132. 128. + 137. 149. 159. 167. 175. 183. 189. 190. 191. 192. 191. 189. 188. + 188. 188. 101. 100. 99. 98. 96. 92. 87. 83. 82. 82. 78. 68. 63. 77. + 105. 129. 143. 155. 166. 172. 175. 179. 182. 181. 184. 185. 182. + 175. 167. 156. 138. 123. 99. 81. 79. 89. 91. 95. 102. 103. 110. 111. + 115. 97. 113. 137. 134. 165. 173. 153. 150. 132. 84. 65. 60. 85. 99. + 60. 32. 42. 65. 42. 40. 56. 85. 124. 139. 134. 132. 101. 56. 36. 33. + 65. 70. 64. 85. 112. 95. 81. 88. 110. 108. 136. 104. 68. 68. 59. 41. + 45. 47. 45. 44. 47. 49. 49. 42. 59. 35. 33. 31. 77. 149. 112. 126. + 171. 172. 170. 178. 189. 222. 181. 113. 90. 89. 112. 124. 128. 135. + 142. 149. 149. 151. 154. 156. 156. 154. 152. 145. 139. 144. 146. + 141. 144. 149. 143. 152. 153. 161. 163. 157. 160. 163. 153. 130. + 133. 137. 135. 130. 126. 128. 132. 152. 168. 187. 209. 224. 209. + 183. 173. 164. 156. 155. 149. 135. 128. 124. 113. 107. 107. 114. + 104. 98. 84. 59. 66. 45. 42. 56. 56. 72. 65. 50. 110. 165. 176. 135. + 86. 77. 65. 48. 53. 49. 45. 48. 60. 57. 37. 52. 96. 135. 138. 131. + 130. 147. 157. 154. 155. 154. 154. 154. 153. 152. 151. 151. 150. + 151. 152. 153. 153. 151. 151. 152. 153. 149. 149. 149. 149. 147. + 146. 144. 143. 143. 143. 144. 144. 138. 131. 130. 133. 137. 149. + 165. 178. 185. 188. 190. 191. 192. 192. 191. 190. 189. 188. 188. + 187. 100. 98. 95. 93. 92. 88. 84. 81. 80. 81. 76. 64. 59. 73. 103. + 129. 143. 154. 166. 171. 175. 180. 182. 181. 183. 184. 182. 175. + 167. 155. 138. 122. 99. 81. 79. 89. 90. 94. 102. 103. 111. 112. 111. + 103. 107. 123. 138. 152. 149. 124. 116. 78. 59. 67. 85. 101. 67. 61. + 38. 39. 84. 65. 82. 70. 92. 105. 90. 79. 89. 72. 45. 47. 37. 62. 77. + 62. 66. 100. 117. 107. 95. 105. 85. 113. 74. 85. 66. 55. 40. 46. 47. + 43. 42. 47. 51. 50. 47. 51. 44. 30. 61. 122. 134. 104. 153. 173. + 172. 191. 183. 201. 203. 126. 72. 106. 106. 106. 131. 130. 124. 149. + 153. 153. 154. 157. 161. 164. 164. 163. 166. 157. 157. 157. 152. + 160. 171. 171. 174. 169. 172. 170. 163. 162. 157. 142. 136. 139. + 139. 136. 131. 128. 128. 129. 151. 166. 184. 206. 223. 211. 190. + 184. 167. 154. 149. 145. 136. 135. 138. 133. 120. 115. 117. 108. + 105. 91. 61. 64. 48. 44. 58. 58. 72. 62. 45. 104. 164. 178. 141. 85. + 72. 64. 47. 56. 46. 46. 48. 55. 50. 38. 61. 110. 134. 137. 131. 134. + 152. 159. 154. 153. 154. 154. 153. 153. 152. 151. 150. 150. 150. + 152. 153. 152. 150. 149. 151. 153. 149. 149. 149. 148. 147. 145. + 143. 142. 143. 141. 141. 140. 135. 129. 133. 141. 157. 167. 182. + 191. 194. 193. 192. 191. 191. 190. 189. 188. 188. 188. 188. 187. + 100. 97. 93. 91. 88. 86. 82. 79. 80. 80. 74. 62. 56. 70. 102. 129. + 142. 154. 166. 171. 175. 180. 182. 181. 183. 184. 181. 174. 166. + 155. 137. 122. 99. 81. 79. 88. 90. 94. 102. 102. 109. 112. 109. 111. + 106. 113. 133. 129. 117. 102. 111. 78. 89. 101. 98. 71. 49. 52. 43. + 57. 98. 49. 101. 122. 115. 86. 56. 76. 104. 67. 27. 41. 50. 66. 82. + 81. 55. 60. 123. 149. 116. 78. 79. 82. 146. 87. 35. 41. 45. 51. 51. + 44. 41. 46. 50. 50. 58. 36. 45. 37. 99. 151. 105. 116. 172. 186. + 176. 200. 200. 202. 142. 63. 86. 93. 118. 127. 117. 128. 145. 138. + 155. 154. 154. 156. 160. 164. 165. 165. 173. 165. 166. 167. 163. + 167. 173. 168. 171. 164. 166. 169. 167. 167. 156. 135. 141. 142. + 140. 135. 131. 129. 128. 127. 144. 164. 186. 210. 224. 211. 189. + 183. 176. 161. 158. 159. 150. 143. 137. 126. 125. 116. 116. 108. + 109. 95. 60. 56. 49. 45. 58. 56. 69. 58. 39. 97. 164. 179. 145. 84. + 69. 64. 47. 58. 44. 46. 47. 50. 46. 41. 71. 122. 133. 136. 132. 137. + 156. 161. 154. 152. 154. 154. 153. 152. 152. 151. 150. 150. 148. + 150. 151. 149. 147. 146. 148. 151. 149. 149. 148. 147. 146. 144. + 143. 142. 144. 140. 137. 136. 132. 129. 137. 149. 173. 181. 191. + 197. 196. 193. 192. 191. 194. 192. 191. 191. 192. 192. 192. 192. 92. + 93. 94. 91. 86. 83. 83. 85. 82. 78. 72. 65. 62. 73. 101. 127. 140. + 152. 164. 169. 173. 178. 180. 179. 182. 183. 180. 173. 166. 156. + 140. 125. 99. 84. 76. 84. 95. 98. 99. 102. 107. 104. 103. 108. 117. + 121. 115. 106. 143. 135. 127. 138. 155. 139. 95. 62. 56. 60. 48. 78. + 104. 74. 121. 107. 111. 78. 73. 115. 92. 36. 40. 44. 45. 58. 106. + 125. 87. 69. 82. 82. 115. 98. 124. 144. 122. 73. 42. 62. 57. 44. 48. + 55. 44. 37. 46. 55. 50. 41. 44. 57. 143. 123. 97. 163. 169. 188. + 186. 194. 205. 166. 60. 77. 91. 105. 118. 121. 121. 127. 135. 141. + 145. 150. 156. 161. 164. 165. 166. 167. 173. 175. 173. 169. 168. + 172. 173. 170. 168. 170. 172. 172. 167. 159. 150. 144. 142. 139. + 135. 132. 130. 129. 128. 127. 141. 157. 184. 211. 221. 212. 192. + 178. 175. 169. 160. 151. 144. 140. 136. 133. 127. 127. 119. 115. + 112. 90. 65. 58. 47. 44. 59. 60. 65. 55. 43. 89. 159. 180. 160. 79. + 73. 46. 42. 63. 47. 44. 53. 56. 40. 47. 91. 131. 137. 130. 132. 146. + 159. 160. 156. 155. 153. 153. 152. 152. 152. 152. 151. 151. 151. + 152. 152. 151. 150. 149. 148. 147. 147. 146. 146. 145. 143. 142. + 142. 141. 138. 139. 137. 132. 130. 138. 155. 169. 189. 191. 195. + 198. 198. 196. 193. 191. 191. 190. 189. 188. 188. 189. 190. 191. 91. + 92. 92. 89. 85. 82. 82. 84. 77. 74. 69. 63. 60. 72. 101. 127. 141. + 153. 165. 170. 173. 178. 180. 179. 182. 183. 180. 173. 166. 155. + 139. 124. 100. 85. 77. 83. 91. 93. 95. 100. 104. 115. 127. 132. 134. + 139. 149. 156. 156. 170. 135. 99. 102. 90. 61. 55. 67. 62. 65. 82. + 93. 86. 125. 93. 89. 110. 110. 101. 61. 29. 40. 34. 56. 37. 50. 82. + 102. 117. 120. 103. 103. 130. 148. 104. 76. 100. 105. 96. 77. 51. + 43. 51. 49. 45. 45. 43. 51. 49. 40. 106. 136. 121. 114. 178. 179. + 186. 193. 197. 186. 68. 61. 73. 94. 107. 119. 122. 122. 127. 135. + 140. 145. 149. 155. 160. 162. 165. 167. 169. 174. 176. 175. 171. + 170. 174. 174. 172. 171. 172. 173. 171. 167. 159. 151. 146. 144. + 141. 137. 134. 131. 130. 128. 127. 137. 153. 181. 209. 221. 214. + 194. 179. 174. 168. 160. 152. 146. 141. 136. 133. 129. 130. 123. + 120. 116. 94. 68. 61. 49. 47. 60. 63. 68. 54. 41. 84. 157. 178. 159. + 94. 69. 46. 42. 58. 44. 44. 54. 53. 42. 57. 101. 134. 136. 132. 135. + 148. 159. 159. 156. 155. 153. 153. 152. 152. 152. 152. 151. 151. + 151. 151. 151. 151. 150. 149. 148. 147. 147. 147. 146. 145. 144. + 143. 142. 141. 138. 136. 133. 132. 137. 152. 170. 183. 190. 192. + 195. 197. 198. 196. 193. 191. 190. 190. 189. 189. 190. 191. 193. + 194. 89. 90. 89. 87. 83. 81. 81. 81. 73. 70. 66. 60. 59. 72. 101. + 128. 142. 154. 165. 171. 174. 178. 181. 180. 183. 183. 180. 173. + 165. 155. 138. 123. 99. 86. 78. 83. 89. 92. 98. 106. 122. 132. 143. + 145. 140. 138. 144. 151. 122. 89. 62. 66. 74. 62. 57. 71. 71. 50. + 75. 91. 86. 85. 114. 105. 114. 133. 102. 59. 42. 45. 52. 36. 39. 45. + 58. 68. 73. 83. 103. 119. 118. 75. 52. 40. 76. 141. 134. 88. 77. 49. + 38. 47. 49. 47. 47. 44. 43. 45. 56. 140. 127. 107. 144. 184. 184. + 200. 198. 197. 110. 29. 52. 88. 98. 111. 122. 123. 123. 128. 135. + 138. 145. 149. 153. 157. 161. 164. 169. 172. 175. 178. 177. 174. + 174. 176. 176. 173. 174. 174. 173. 171. 166. 159. 153. 149. 147. + 144. 140. 136. 132. 130. 129. 129. 133. 150. 178. 206. 222. 217. + 197. 180. 171. 167. 160. 154. 148. 142. 136. 132. 129. 131. 126. + 123. 119. 95. 68. 61. 50. 51. 61. 66. 72. 53. 40. 76. 156. 174. 155. + 116. 61. 46. 41. 52. 43. 47. 53. 47. 43. 70. 114. 137. 136. 135. + 140. 151. 158. 159. 156. 154. 153. 153. 153. 152. 152. 151. 151. + 151. 150. 151. 151. 150. 150. 148. 147. 146. 147. 147. 146. 146. + 144. 143. 141. 140. 139. 134. 130. 135. 149. 168. 184. 193. 192. + 193. 195. 197. 197. 195. 193. 191. 189. 189. 190. 191. 193. 195. + 197. 198. 86. 86. 85. 84. 81. 79. 79. 78. 73. 70. 65. 60. 58. 71. + 100. 127. 143. 155. 166. 171. 174. 178. 180. 179. 183. 183. 180. + 173. 165. 154. 137. 122. 96. 85. 80. 85. 91. 95. 105. 117. 131. 128. + 128. 134. 136. 128. 115. 106. 104. 49. 54. 88. 77. 63. 66. 59. 61. + 66. 93. 79. 79. 105. 116. 124. 121. 113. 68. 38. 49. 58. 52. 48. 51. + 52. 47. 50. 67. 74. 71. 72. 102. 35. 22. 48. 90. 133. 131. 111. 73. + 51. 46. 51. 45. 40. 47. 51. 35. 41. 104. 138. 122. 109. 179. 181. + 182. 207. 202. 133. 38. 53. 54. 100. 103. 114. 124. 125. 125. 129. + 134. 136. 145. 148. 151. 155. 158. 163. 169. 174. 175. 178. 179. + 177. 177. 179. 178. 174. 176. 175. 173. 169. 164. 158. 153. 150. + 148. 147. 143. 138. 133. 130. 129. 130. 134. 150. 177. 204. 222. + 220. 200. 180. 168. 165. 160. 156. 151. 144. 138. 133. 126. 130. + 126. 123. 117. 92. 65. 58. 49. 53. 58. 69. 76. 53. 40. 70. 155. 170. + 148. 135. 54. 43. 41. 48. 47. 51. 51. 39. 42. 83. 126. 139. 135. + 139. 147. 155. 158. 158. 155. 154. 154. 154. 153. 152. 152. 151. + 150. 150. 150. 150. 150. 150. 149. 148. 146. 146. 146. 146. 146. + 146. 144. 142. 140. 139. 138. 133. 132. 143. 162. 180. 191. 194. + 193. 194. 195. 196. 195. 194. 193. 192. 190. 190. 192. 194. 196. + 199. 201. 202. 84. 83. 81. 80. 79. 78. 76. 75. 75. 72. 66. 60. 58. + 70. 98. 125. 143. 155. 166. 171. 174. 178. 179. 178. 182. 182. 179. + 172. 165. 154. 137. 122. 95. 84. 79. 85. 91. 96. 106. 117. 112. 107. + 110. 123. 129. 118. 99. 86. 79. 93. 100. 90. 76. 67. 58. 47. 69. + 104. 104. 53. 79. 143. 125. 120. 70. 78. 69. 52. 52. 45. 37. 54. 53. + 48. 36. 41. 70. 83. 67. 51. 78. 48. 48. 55. 81. 124. 132. 122. 86. + 59. 47. 50. 43. 38. 42. 43. 34. 61. 145. 129. 111. 148. 198. 182. + 189. 197. 172. 43. 32. 55. 75. 91. 106. 116. 124. 125. 126. 130. + 134. 135. 144. 146. 149. 152. 156. 161. 168. 173. 173. 178. 180. + 178. 178. 180. 178. 174. 176. 175. 172. 168. 162. 156. 151. 149. + 147. 147. 144. 139. 133. 129. 129. 131. 137. 152. 175. 201. 221. + 223. 203. 180. 166. 164. 160. 156. 152. 146. 139. 134. 127. 131. + 127. 123. 115. 89. 62. 55. 47. 53. 53. 70. 79. 52. 42. 64. 154. 167. + 142. 146. 55. 40. 40. 45. 55. 55. 49. 35. 45. 93. 134. 138. 135. + 144. 154. 159. 158. 156. 155. 154. 154. 154. 153. 152. 152. 151. + 150. 150. 149. 149. 149. 149. 148. 147. 145. 145. 145. 146. 146. + 145. 144. 141. 138. 136. 130. 131. 138. 155. 175. 189. 193. 192. + 194. 194. 194. 194. 194. 194. 194. 194. 192. 193. 195. 198. 200. + 202. 204. 204. 81. 79. 77. 77. 77. 76. 74. 72. 75. 71. 66. 60. 57. + 69. 97. 124. 143. 154. 165. 170. 172. 176. 178. 177. 180. 181. 178. + 172. 165. 154. 138. 124. 97. 84. 78. 83. 90. 93. 99. 108. 104. 106. + 114. 121. 113. 95. 85. 85. 81. 116. 86. 68. 102. 78. 47. 84. 103. + 98. 70. 53. 91. 138. 107. 110. 58. 70. 75. 51. 42. 48. 44. 55. 43. + 55. 60. 51. 44. 53. 60. 58. 81. 48. 30. 37. 86. 133. 131. 127. 103. + 59. 31. 34. 40. 43. 41. 33. 41. 96. 144. 123. 107. 189. 193. 186. + 199. 185. 90. 32. 45. 51. 81. 85. 108. 117. 124. 125. 126. 130. 133. + 133. 142. 145. 148. 151. 154. 159. 165. 169. 171. 176. 179. 178. + 179. 180. 177. 172. 174. 173. 170. 166. 160. 154. 148. 145. 144. + 145. 143. 138. 131. 127. 128. 131. 138. 152. 172. 195. 217. 224. + 205. 180. 165. 163. 159. 156. 152. 147. 141. 137. 131. 134. 130. + 123. 113. 86. 60. 54. 46. 55. 49. 70. 81. 50. 42. 58. 152. 166. 139. + 153. 68. 40. 40. 43. 60. 56. 48. 39. 55. 104. 139. 137. 134. 148. + 161. 162. 158. 155. 154. 153. 155. 154. 154. 153. 151. 150. 150. + 149. 148. 148. 148. 148. 147. 146. 145. 144. 143. 144. 145. 144. + 142. 139. 135. 133. 123. 132. 148. 168. 186. 195. 196. 194. 194. + 193. 193. 193. 193. 194. 195. 196. 196. 197. 199. 201. 203. 204. + 205. 205. 79. 77. 74. 74. 75. 75. 73. 70. 71. 68. 63. 58. 56. 68. + 97. 124. 142. 153. 164. 169. 171. 175. 176. 175. 178. 179. 177. 171. + 165. 155. 139. 125. 98. 83. 75. 82. 91. 94. 97. 103. 111. 112. 117. + 118. 104. 90. 93. 107. 128. 108. 75. 90. 121. 86. 64. 111. 102. 65. + 45. 65. 75. 110. 103. 101. 92. 70. 66. 44. 40. 60. 55. 55. 59. 52. + 53. 46. 39. 57. 62. 38. 67. 49. 41. 56. 100. 116. 114. 153. 135. 81. + 40. 32. 36. 40. 41. 34. 62. 126. 125. 115. 139. 197. 189. 196. 193. + 131. 31. 58. 48. 57. 71. 91. 108. 116. 123. 124. 126. 131. 133. 133. + 141. 143. 147. 150. 153. 156. 161. 165. 168. 174. 178. 178. 178. + 179. 176. 170. 171. 170. 168. 164. 158. 151. 145. 141. 140. 142. + 141. 136. 129. 126. 128. 131. 136. 148. 165. 187. 213. 224. 208. + 182. 165. 162. 159. 155. 152. 148. 143. 139. 132. 135. 129. 120. + 108. 80. 55. 51. 48. 58. 46. 69. 80. 46. 40. 52. 148. 166. 141. 158. + 90. 43. 41. 41. 61. 54. 49. 49. 71. 116. 143. 137. 134. 151. 166. + 165. 158. 155. 154. 153. 155. 155. 154. 153. 151. 150. 149. 149. + 148. 148. 148. 147. 147. 145. 144. 143. 141. 142. 143. 143. 141. + 137. 133. 131. 127. 142. 163. 182. 192. 196. 197. 197. 193. 192. + 192. 192. 193. 195. 197. 199. 200. 201. 203. 204. 205. 205. 204. + 204. 78. 76. 73. 73. 75. 75. 72. 69. 67. 64. 60. 55. 55. 68. 98. + 125. 141. 152. 163. 168. 170. 174. 175. 174. 177. 178. 176. 171. + 165. 156. 140. 126. 96. 81. 74. 83. 95. 99. 101. 105. 107. 102. 104. + 111. 113. 115. 131. 151. 108. 68. 87. 111. 84. 79. 104. 105. 60. 60. + 65. 63. 33. 109. 139. 88. 102. 58. 63. 60. 50. 56. 47. 51. 44. 38. + 50. 51. 43. 68. 80. 49. 47. 52. 45. 50. 99. 110. 86. 112. 178. 124. + 76. 51. 34. 30. 37. 40. 87. 144. 118. 107. 187. 187. 198. 208. 177. + 50. 36. 45. 57. 51. 68. 93. 108. 116. 122. 124. 126. 131. 133. 132. + 140. 143. 147. 150. 152. 155. 159. 162. 166. 172. 176. 177. 177. + 178. 174. 169. 168. 168. 166. 163. 157. 150. 143. 138. 138. 140. + 140. 135. 128. 124. 127. 131. 132. 144. 160. 182. 210. 224. 209. + 184. 166. 162. 158. 154. 151. 148. 144. 141. 130. 133. 126. 116. + 103. 75. 50. 46. 51. 61. 45. 69. 79. 42. 38. 47. 145. 167. 144. 162. + 106. 47. 41. 39. 59. 51. 50. 58. 84. 125. 146. 136. 133. 153. 169. + 167. 158. 154. 154. 153. 156. 155. 154. 153. 151. 150. 149. 148. + 147. 147. 147. 147. 146. 145. 144. 143. 140. 141. 142. 142. 140. + 136. 132. 129. 137. 154. 176. 191. 195. 194. 195. 197. 192. 192. + 191. 191. 192. 195. 198. 200. 203. 204. 205. 206. 206. 205. 204. + 203. 77. 76. 74. 74. 76. 76. 75. 73. 70. 67. 63. 56. 53. 67. 99. + 128. 143. 152. 161. 167. 171. 175. 174. 169. 176. 177. 174. 168. + 162. 153. 138. 124. 107. 73. 77. 69. 99. 135. 101. 93. 107. 109. + 114. 134. 155. 138. 93. 65. 47. 103. 119. 119. 71. 124. 100. 46. 41. + 105. 58. 83. 51. 122. 139. 105. 131. 63. 53. 40. 72. 58. 65. 41. 59. + 32. 47. 51. 39. 56. 68. 61. 53. 47. 62. 60. 104. 130. 127. 68. 111. + 156. 148. 42. 42. 43. 19. 58. 138. 117. 114. 134. 202. 197. 197. + 216. 76. 45. 37. 50. 64. 47. 81. 91. 102. 109. 119. 125. 127. 129. + 131. 134. 137. 141. 146. 150. 152. 155. 159. 161. 161. 167. 173. + 176. 174. 171. 170. 171. 172. 167. 163. 163. 160. 151. 140. 134. + 136. 134. 133. 131. 127. 123. 124. 127. 134. 138. 157. 183. 205. + 223. 214. 185. 161. 160. 157. 151. 147. 145. 141. 137. 136. 129. + 126. 120. 96. 63. 46. 47. 55. 60. 51. 74. 82. 44. 33. 48. 133. 167. + 135. 141. 130. 54. 34. 45. 55. 55. 39. 52. 106. 138. 137. 136. 144. + 152. 161. 164. 161. 156. 155. 155. 153. 153. 152. 151. 150. 150. + 149. 148. 147. 147. 146. 145. 145. 144. 143. 143. 141. 144. 142. + 137. 136. 136. 133. 126. 146. 169. 188. 192. 192. 197. 196. 189. + 193. 193. 193. 194. 196. 199. 202. 204. 208. 208. 208. 207. 205. + 203. 201. 200. 79. 77. 75. 75. 75. 74. 72. 70. 69. 66. 61. 55. 52. + 65. 97. 127. 142. 152. 161. 167. 171. 175. 174. 170. 176. 177. 175. + 168. 162. 153. 138. 124. 95. 68. 80. 79. 107. 135. 96. 83. 121. 138. + 153. 155. 131. 82. 50. 53. 88. 122. 140. 106. 99. 81. 70. 43. 68. + 98. 86. 79. 80. 131. 128. 115. 105. 96. 53. 58. 63. 46. 63. 45. 41. + 39. 37. 48. 44. 62. 96. 71. 87. 52. 68. 79. 115. 156. 163. 88. 57. + 129. 157. 58. 33. 33. 36. 87. 120. 132. 113. 163. 202. 212. 205. + 141. 53. 33. 36. 57. 73. 49. 74. 80. 102. 109. 119. 125. 127. 128. + 131. 134. 137. 141. 145. 149. 152. 154. 158. 160. 161. 165. 169. + 171. 172. 171. 170. 170. 170. 167. 164. 162. 157. 150. 141. 135. + 135. 134. 133. 131. 127. 123. 123. 125. 133. 138. 157. 181. 203. + 223. 219. 195. 161. 159. 155. 151. 147. 144. 140. 137. 133. 129. + 126. 117. 91. 59. 44. 46. 56. 63. 54. 76. 83. 46. 34. 47. 120. 164. + 143. 147. 131. 55. 34. 47. 53. 50. 42. 64. 115. 141. 136. 135. 147. + 154. 161. 163. 159. 155. 154. 155. 154. 153. 153. 152. 151. 150. + 149. 149. 147. 147. 146. 146. 145. 144. 143. 143. 142. 142. 141. + 139. 136. 133. 132. 133. 155. 175. 191. 193. 193. 197. 196. 191. + 192. 193. 194. 196. 199. 201. 203. 204. 208. 208. 207. 207. 205. + 203. 202. 201. 81. 79. 76. 75. 74. 73. 70. 68. 67. 64. 59. 52. 49. + 63. 96. 125. 141. 151. 162. 167. 171. 175. 174. 171. 176. 177. 175. + 169. 163. 153. 138. 124. 96. 71. 76. 74. 101. 133. 117. 117. 144. + 135. 131. 135. 115. 68. 51. 72. 114. 129. 103. 102. 92. 75. 42. 63. + 91. 95. 115. 71. 108. 133. 114. 129. 85. 131. 52. 68. 60. 47. 62. + 46. 27. 47. 31. 49. 53. 73. 122. 83. 71. 45. 82. 108. 129. 179. 193. + 110. 40. 88. 125. 57. 30. 26. 50. 107. 134. 128. 125. 189. 206. 220. + 153. 43. 37. 26. 36. 61. 81. 53. 71. 79. 102. 109. 118. 125. 127. + 128. 131. 133. 136. 140. 144. 148. 150. 153. 156. 159. 161. 161. + 162. 165. 168. 170. 170. 168. 168. 167. 164. 160. 154. 147. 141. + 136. 132. 133. 133. 130. 126. 123. 122. 122. 130. 135. 154. 176. + 196. 220. 224. 207. 161. 158. 153. 150. 147. 143. 139. 136. 130. + 129. 125. 112. 83. 54. 42. 46. 55. 65. 58. 78. 84. 47. 34. 45. 104. + 160. 154. 153. 133. 60. 35. 48. 49. 44. 46. 80. 127. 143. 136. 136. + 152. 156. 160. 160. 157. 153. 153. 154. 154. 154. 153. 152. 152. + 151. 150. 150. 147. 147. 147. 146. 145. 144. 144. 143. 143. 139. + 139. 141. 135. 129. 133. 144. 168. 183. 195. 195. 193. 196. 196. + 192. 192. 194. 197. 200. 203. 204. 205. 205. 207. 207. 207. 207. + 206. 204. 203. 202. 81. 78. 76. 75. 74. 73. 70. 68. 66. 62. 56. 49. + 46. 61. 94. 124. 140. 151. 162. 167. 171. 174. 174. 172. 176. 177. + 176. 170. 164. 154. 138. 123. 99. 77. 75. 68. 87. 120. 126. 140. + 144. 112. 98. 118. 121. 84. 67. 90. 122. 108. 67. 90. 82. 85. 58. + 84. 88. 104. 119. 66. 113. 119. 110. 143. 77. 130. 54. 48. 56. 55. + 55. 39. 33. 47. 36. 52. 61. 80. 115. 88. 56. 73. 113. 115. 116. 164. + 184. 127. 51. 53. 78. 44. 29. 25. 70. 135. 127. 97. 160. 203. 206. + 194. 81. 38. 37. 31. 37. 60. 84. 56. 74. 88. 101. 109. 118. 124. + 126. 128. 130. 133. 135. 139. 143. 146. 149. 151. 154. 157. 159. + 157. 156. 159. 164. 168. 168. 166. 165. 166. 164. 157. 150. 145. + 140. 134. 127. 131. 132. 129. 125. 123. 121. 118. 129. 134. 151. + 169. 188. 214. 225. 214. 163. 157. 152. 151. 149. 144. 139. 137. + 129. 130. 124. 104. 74. 49. 43. 47. 52. 67. 61. 77. 82. 47. 34. 41. + 94. 157. 160. 154. 135. 70. 38. 45. 46. 39. 52. 96. 135. 142. 137. + 139. 156. 158. 159. 157. 154. 152. 152. 153. 154. 153. 153. 153. + 152. 152. 151. 151. 148. 148. 147. 146. 145. 145. 144. 144. 143. + 137. 138. 141. 135. 127. 138. 158. 180. 190. 196. 195. 192. 194. + 195. 193. 193. 196. 200. 204. 207. 207. 206. 206. 207. 207. 207. + 207. 206. 205. 204. 203. 80. 78. 76. 75. 75. 75. 73. 71. 65. 61. 55. + 47. 44. 59. 92. 123. 138. 151. 163. 168. 170. 173. 175. 174. 176. + 178. 176. 171. 165. 155. 138. 123. 92. 80. 78. 73. 80. 98. 106. 120. + 120. 110. 118. 140. 128. 75. 56. 83. 115. 82. 95. 81. 93. 72. 93. + 80. 74. 120. 98. 69. 102. 99. 116. 153. 75. 98. 74. 23. 46. 50. 45. + 42. 49. 41. 45. 52. 63. 79. 86. 84. 77. 124. 125. 81. 68. 108. 119. + 97. 42. 41. 59. 34. 30. 42. 99. 149. 118. 123. 204. 205. 186. 111. + 25. 51. 40. 37. 40. 62. 91. 60. 73. 89. 101. 108. 118. 124. 126. + 127. 130. 133. 134. 137. 142. 145. 147. 149. 152. 155. 157. 154. + 153. 155. 161. 165. 165. 164. 162. 165. 162. 153. 147. 144. 136. + 128. 122. 129. 133. 129. 126. 125. 122. 116. 131. 136. 151. 167. + 185. 212. 226. 218. 166. 157. 151. 152. 151. 144. 138. 137. 129. + 130. 120. 94. 64. 47. 45. 49. 48. 68. 63. 75. 78. 47. 34. 39. 88. + 153. 162. 150. 138. 85. 43. 41. 43. 38. 62. 109. 137. 140. 140. 144. + 159. 159. 158. 155. 153. 151. 151. 152. 153. 153. 152. 152. 152. + 152. 151. 151. 148. 148. 147. 147. 146. 145. 144. 144. 143. 137. + 136. 140. 134. 130. 146. 171. 188. 193. 196. 194. 191. 192. 193. + 193. 195. 198. 203. 207. 209. 208. 207. 205. 206. 206. 207. 207. + 207. 206. 205. 205. 81. 79. 77. 76. 77. 77. 75. 73. 64. 60. 53. 45. + 43. 58. 92. 122. 137. 151. 164. 168. 170. 173. 175. 175. 175. 178. + 177. 172. 166. 155. 138. 123. 93. 81. 72. 73. 82. 94. 107. 117. 109. + 112. 123. 135. 116. 71. 60. 89. 80. 81. 115. 100. 78. 70. 93. 72. + 79. 124. 70. 75. 100. 83. 120. 156. 85. 70. 107. 29. 43. 46. 48. 58. + 56. 41. 45. 47. 61. 77. 72. 83. 98. 150. 134. 87. 69. 88. 72. 58. + 38. 42. 45. 26. 57. 90. 118. 110. 117. 161. 185. 178. 158. 54. 23. + 27. 37. 39. 42. 66. 102. 66. 68. 81. 100. 108. 117. 123. 126. 127. + 130. 132. 133. 136. 141. 144. 145. 147. 150. 153. 154. 153. 153. + 155. 158. 161. 162. 162. 160. 163. 158. 150. 146. 143. 132. 118. + 119. 129. 135. 132. 130. 131. 126. 119. 133. 137. 151. 167. 185. + 213. 228. 219. 166. 155. 148. 151. 151. 143. 137. 136. 129. 129. + 113. 80. 53. 45. 48. 51. 45. 69. 64. 72. 75. 47. 36. 40. 77. 145. + 163. 148. 142. 101. 49. 40. 38. 41. 77. 122. 138. 139. 144. 147. + 160. 158. 157. 154. 153. 152. 151. 151. 151. 151. 151. 151. 151. + 151. 151. 151. 149. 148. 148. 147. 146. 145. 145. 145. 142. 138. + 135. 135. 133. 138. 158. 181. 193. 195. 195. 194. 192. 191. 192. + 193. 198. 201. 204. 207. 209. 208. 206. 205. 205. 206. 207. 207. + 208. 207. 207. 206. 84. 82. 80. 78. 78. 77. 74. 72. 64. 60. 53. 45. + 42. 57. 92. 123. 136. 150. 164. 169. 169. 172. 175. 176. 175. 178. + 177. 173. 167. 156. 138. 123. 97. 82. 69. 82. 103. 115. 122. 120. + 107. 111. 110. 107. 96. 75. 75. 99. 65. 99. 110. 102. 67. 78. 73. + 66. 106. 108. 46. 75. 113. 77. 114. 149. 106. 56. 116. 52. 48. 51. + 62. 61. 51. 53. 38. 41. 62. 80. 94. 94. 89. 128. 135. 127. 92. 88. + 62. 49. 43. 39. 35. 47. 115. 140. 135. 101. 110. 145. 145. 160. 129. + 55. 49. 34. 39. 42. 41. 67. 109. 72. 68. 80. 100. 108. 117. 123. + 125. 127. 129. 132. 132. 135. 140. 142. 144. 146. 149. 151. 152. + 153. 156. 156. 157. 157. 159. 161. 160. 161. 155. 147. 145. 143. + 128. 108. 119. 132. 139. 136. 135. 138. 133. 124. 129. 131. 145. + 163. 184. 213. 227. 216. 165. 151. 144. 149. 150. 141. 134. 134. + 128. 125. 103. 67. 43. 42. 49. 50. 44. 70. 65. 70. 73. 49. 40. 43. + 59. 136. 167. 150. 147. 113. 55. 42. 33. 46. 93. 136. 141. 141. 149. + 149. 159. 157. 156. 154. 153. 152. 151. 150. 149. 150. 150. 150. + 150. 150. 150. 150. 149. 149. 148. 147. 146. 146. 145. 145. 141. + 139. 135. 131. 133. 147. 170. 188. 196. 195. 195. 195. 194. 193. + 194. 195. 202. 203. 205. 207. 208. 207. 205. 204. 205. 205. 206. + 207. 208. 208. 208. 207. 88. 85. 82. 80. 79. 76. 73. 71. 65. 60. 53. + 45. 42. 57. 92. 123. 136. 150. 164. 169. 169. 172. 175. 176. 175. + 178. 178. 173. 167. 156. 138. 123. 92. 81. 76. 106. 134. 133. 118. + 94. 98. 118. 123. 108. 85. 64. 66. 88. 91. 114. 121. 66. 94. 68. 70. + 56. 132. 87. 34. 71. 127. 75. 103. 140. 120. 46. 99. 64. 52. 58. 69. + 45. 44. 68. 31. 38. 65. 85. 124. 107. 51. 67. 96. 116. 57. 42. 33. + 32. 36. 30. 42. 91. 165. 161. 157. 155. 138. 144. 172. 184. 96. 44. + 28. 45. 46. 46. 40. 64. 110. 76. 72. 87. 100. 107. 117. 123. 125. + 127. 129. 132. 132. 135. 139. 142. 143. 145. 148. 150. 150. 154. + 158. 158. 156. 155. 157. 160. 159. 159. 153. 145. 145. 144. 125. + 102. 120. 134. 142. 140. 140. 143. 138. 128. 123. 124. 139. 158. + 181. 212. 224. 212. 163. 149. 141. 147. 148. 139. 131. 132. 127. + 122. 97. 59. 37. 40. 49. 49. 44. 72. 67. 70. 73. 50. 43. 45. 45. + 130. 170. 154. 151. 120. 59. 45. 29. 50. 105. 145. 144. 144. 153. + 149. 158. 157. 155. 154. 154. 153. 151. 150. 148. 148. 149. 149. + 149. 149. 149. 149. 149. 149. 148. 147. 147. 146. 145. 145. 140. + 140. 135. 128. 132. 153. 177. 191. 197. 196. 196. 197. 196. 195. + 195. 197. 204. 205. 206. 207. 206. 205. 204. 203. 204. 205. 206. + 207. 208. 208. 208. 208. 86. 81. 76. 76. 79. 79. 75. 70. 62. 66. 61. + 46. 43. 66. 101. 125. 142. 150. 161. 168. 170. 170. 171. 173. 176. + 180. 180. 174. 166. 155. 139. 125. 107. 104. 105. 109. 104. 95. 96. + 104. 100. 115. 116. 108. 93. 63. 62. 98. 110. 100. 98. 85. 66. 50. + 59. 104. 120. 75. 54. 42. 119. 82. 86. 142. 143. 53. 94. 124. 44. + 51. 49. 44. 58. 71. 46. 42. 44. 71. 52. 41. 40. 46. 89. 101. 86. 38. + 34. 35. 51. 33. 11. 155. 164. 174. 169. 174. 176. 190. 172. 111. 56. + 37. 37. 35. 44. 41. 40. 67. 96. 83. 68. 85. 101. 109. 119. 126. 128. + 128. 129. 130. 132. 135. 139. 141. 143. 144. 147. 149. 152. 152. + 151. 152. 153. 156. 158. 159. 159. 158. 155. 150. 146. 139. 125. + 111. 125. 138. 139. 124. 118. 128. 136. 133. 115. 125. 133. 145. + 174. 204. 209. 196. 150. 147. 150. 148. 142. 145. 140. 122. 129. + 113. 68. 39. 44. 46. 45. 57. 54. 58. 77. 60. 71. 48. 41. 44. 46. + 116. 169. 159. 138. 134. 61. 43. 38. 45. 115. 149. 143. 145. 144. + 160. 159. 158. 156. 154. 152. 151. 151. 150. 150. 151. 151. 151. + 151. 150. 149. 148. 148. 148. 147. 146. 144. 143. 142. 142. 136. + 138. 133. 127. 138. 165. 185. 190. 199. 197. 194. 192. 192. 195. + 198. 201. 204. 203. 203. 204. 204. 206. 207. 208. 206. 207. 209. + 210. 210. 209. 207. 207. 86. 83. 80. 79. 81. 80. 77. 74. 63. 67. 63. + 51. 49. 71. 104. 127. 144. 152. 162. 169. 171. 171. 172. 174. 176. + 180. 180. 174. 166. 155. 139. 126. 105. 90. 80. 82. 85. 87. 93. 101. + 100. 117. 113. 99. 90. 74. 73. 93. 91. 126. 106. 88. 66. 37. 80. + 148. 86. 71. 67. 48. 109. 97. 85. 130. 172. 82. 67. 133. 49. 48. 51. + 74. 60. 62. 44. 29. 46. 49. 56. 73. 58. 120. 136. 56. 24. 36. 62. + 45. 29. 26. 64. 174. 162. 189. 187. 183. 190. 156. 104. 57. 32. 28. + 36. 43. 47. 43. 41. 68. 98. 86. 73. 90. 100. 108. 117. 123. 124. + 125. 127. 129. 132. 135. 139. 142. 144. 145. 148. 150. 151. 151. + 151. 152. 153. 155. 158. 159. 158. 158. 155. 150. 147. 141. 128. + 116. 135. 130. 106. 72. 61. 77. 95. 101. 121. 125. 126. 135. 162. + 191. 193. 178. 155. 148. 149. 147. 140. 140. 137. 124. 125. 96. 56. + 39. 44. 47. 46. 51. 56. 61. 74. 59. 69. 49. 45. 48. 39. 103. 164. + 160. 133. 136. 69. 41. 49. 63. 126. 150. 141. 145. 146. 159. 159. + 158. 156. 154. 152. 151. 151. 150. 150. 150. 151. 151. 150. 150. + 149. 148. 148. 148. 147. 145. 144. 143. 142. 142. 138. 139. 133. + 130. 144. 171. 189. 192. 199. 197. 195. 194. 194. 197. 201. 203. + 204. 204. 204. 204. 205. 206. 208. 209. 207. 208. 209. 210. 209. + 208. 207. 206. 84. 83. 82. 80. 79. 78. 76. 76. 64. 68. 66. 58. 59. + 79. 109. 130. 146. 154. 164. 170. 171. 172. 173. 175. 176. 180. 180. + 175. 167. 156. 140. 126. 105. 83. 66. 70. 83. 91. 97. 102. 104. 119. + 112. 93. 86. 84. 84. 91. 92. 141. 109. 79. 42. 32. 104. 128. 66. 77. + 85. 58. 94. 115. 86. 123. 160. 113. 53. 143. 62. 44. 43. 69. 57. 72. + 62. 21. 42. 31. 47. 68. 72. 129. 133. 59. 43. 44. 48. 29. 30. 40. + 96. 164. 172. 195. 180. 188. 191. 120. 49. 26. 33. 37. 39. 43. 49. + 44. 43. 71. 102. 92. 78. 95. 103. 109. 117. 121. 123. 124. 127. 130. + 132. 135. 139. 142. 144. 146. 149. 152. 150. 150. 150. 151. 153. + 155. 157. 158. 157. 158. 156. 152. 149. 145. 134. 123. 135. 133. + 116. 93. 86. 98. 106. 105. 107. 109. 111. 122. 152. 180. 182. 167. + 160. 148. 147. 147. 138. 135. 135. 128. 116. 74. 45. 43. 46. 49. 51. + 48. 58. 67. 72. 60. 66. 49. 49. 51. 34. 87. 160. 165. 130. 140. 82. + 40. 61. 87. 139. 151. 140. 146. 150. 157. 158. 157. 155. 154. 152. + 151. 151. 150. 150. 150. 151. 151. 150. 149. 148. 148. 148. 147. + 146. 145. 144. 143. 142. 141. 140. 138. 132. 134. 152. 179. 193. + 194. 198. 197. 196. 196. 198. 201. 204. 206. 206. 205. 205. 206. + 206. 208. 209. 210. 209. 209. 210. 210. 209. 208. 207. 206. 79. 80. + 80. 79. 76. 74. 74. 75. 65. 68. 68. 66. 70. 88. 114. 134. 148. 155. + 164. 169. 170. 171. 172. 174. 176. 180. 180. 175. 167. 157. 141. + 127. 102. 82. 70. 79. 93. 99. 100. 101. 110. 117. 113. 96. 82. 77. + 82. 92. 75. 94. 75. 53. 37. 83. 141. 92. 71. 85. 90. 63. 78. 119. + 83. 121. 128. 142. 70. 138. 73. 35. 39. 49. 51. 111. 112. 49. 40. + 32. 33. 40. 119. 103. 66. 34. 67. 60. 56. 63. 64. 87. 106. 131. 161. + 162. 163. 195. 138. 79. 31. 34. 58. 63. 51. 41. 47. 44. 44. 74. 108. + 97. 81. 96. 109. 114. 119. 123. 123. 125. 129. 133. 130. 133. 138. + 141. 143. 145. 148. 151. 148. 148. 149. 151. 153. 155. 157. 158. + 157. 158. 157. 153. 151. 149. 141. 132. 116. 124. 128. 126. 129. + 133. 127. 114. 101. 110. 121. 136. 160. 180. 179. 166. 163. 148. + 145. 147. 138. 133. 134. 130. 102. 57. 41. 51. 49. 49. 56. 52. 59. + 75. 72. 66. 66. 50. 51. 49. 34. 74. 156. 171. 130. 144. 93. 43. 65. + 105. 147. 150. 141. 148. 154. 155. 157. 156. 155. 153. 152. 151. + 151. 151. 149. 150. 150. 150. 150. 149. 148. 147. 147. 147. 146. + 145. 144. 142. 142. 141. 139. 135. 131. 138. 160. 185. 196. 194. + 195. 195. 196. 197. 200. 203. 206. 208. 207. 207. 206. 207. 208. + 209. 210. 211. 210. 210. 210. 209. 209. 208. 207. 207. 78. 79. 80. + 78. 75. 74. 74. 75. 67. 68. 69. 72. 79. 96. 119. 138. 149. 155. 163. + 168. 169. 169. 171. 173. 176. 180. 180. 175. 168. 157. 142. 128. 97. + 81. 73. 81. 91. 94. 95. 98. 111. 111. 115. 105. 75. 56. 69. 92. 72. + 67. 51. 42. 77. 121. 110. 69. 79. 84. 80. 73. 80. 115. 82. 119. 118. + 153. 101. 128. 92. 23. 42. 55. 45. 137. 157. 106. 45. 33. 31. 54. + 113. 89. 46. 21. 74. 88. 99. 112. 118. 132. 116. 113. 119. 134. 185. + 173. 60. 42. 30. 41. 63. 72. 61. 46. 44. 42. 44. 78. 113. 101. 81. + 93. 111. 115. 120. 123. 123. 125. 129. 133. 128. 132. 136. 139. 141. + 143. 146. 148. 146. 147. 149. 151. 153. 155. 156. 157. 156. 159. + 158. 154. 153. 152. 147. 140. 131. 132. 128. 123. 127. 134. 133. + 125. 125. 142. 162. 174. 183. 185. 175. 162. 161. 147. 144. 145. + 138. 134. 132. 123. 81. 47. 43. 55. 48. 46. 57. 59. 60. 84. 72. 74. + 67. 52. 51. 44. 36. 63. 146. 173. 131. 143. 96. 48. 66. 116. 147. + 148. 144. 149. 157. 154. 156. 156. 154. 153. 151. 151. 151. 151. + 149. 149. 150. 150. 149. 149. 148. 147. 147. 146. 146. 144. 143. + 142. 141. 141. 137. 132. 130. 142. 166. 188. 196. 193. 193. 194. + 196. 198. 201. 204. 206. 208. 207. 207. 207. 207. 208. 209. 210. + 211. 211. 210. 210. 209. 209. 208. 208. 208. 81. 80. 80. 79. 78. 77. + 77. 76. 68. 66. 68. 75. 85. 101. 123. 141. 150. 156. 164. 167. 168. + 168. 170. 172. 176. 179. 180. 175. 168. 158. 143. 129. 100. 84. 73. + 77. 84. 87. 94. 102. 108. 109. 122. 113. 67. 39. 58. 88. 75. 79. 53. + 57. 119. 100. 35. 63. 79. 81. 74. 91. 100. 114. 94. 122. 103. 129. + 124. 133. 129. 34. 37. 59. 42. 120. 156. 135. 50. 26. 38. 88. 56. + 68. 79. 75. 104. 101. 121. 145. 168. 135. 105. 112. 105. 161. 216. + 102. 34. 40. 41. 40. 48. 59. 59. 51. 45. 42. 44. 79. 115. 103. 82. + 93. 110. 114. 119. 121. 121. 122. 126. 130. 128. 132. 135. 138. 139. + 141. 143. 145. 144. 145. 148. 151. 153. 155. 156. 156. 156. 159. + 159. 155. 153. 153. 151. 146. 154. 148. 138. 129. 132. 143. 151. + 151. 143. 165. 188. 199. 197. 188. 174. 162. 157. 146. 144. 142. + 137. 136. 126. 104. 60. 44. 44. 52. 47. 44. 53. 63. 59. 91. 71. 79. + 67. 54. 54. 44. 38. 53. 132. 168. 133. 137. 91. 57. 75. 127. 145. + 146. 148. 149. 159. 156. 156. 155. 153. 152. 151. 151. 151. 151. + 149. 149. 149. 149. 149. 148. 147. 147. 147. 146. 145. 144. 143. + 142. 141. 140. 134. 130. 132. 146. 170. 189. 195. 193. 192. 194. + 197. 200. 203. 205. 207. 207. 207. 207. 207. 207. 208. 209. 210. + 211. 210. 210. 209. 209. 209. 209. 210. 211. 82. 79. 77. 77. 79. 80. + 77. 74. 68. 64. 66. 76. 88. 104. 125. 143. 153. 158. 165. 168. 168. + 169. 171. 173. 175. 179. 180. 176. 169. 159. 143. 130. 105. 87. 74. + 77. 86. 91. 97. 104. 106. 117. 137. 121. 65. 40. 63. 85. 58. 75. 68. + 93. 115. 66. 36. 69. 73. 83. 70. 97. 108. 103. 108. 122. 85. 103. + 136. 128. 147. 76. 44. 57. 58. 90. 124. 114. 57. 37. 54. 73. 50. 67. + 105. 113. 124. 116. 151. 182. 156. 111. 88. 122. 144. 187. 166. 47. + 47. 53. 54. 49. 48. 53. 56. 55. 50. 45. 44. 77. 113. 103. 84. 96. + 110. 115. 120. 123. 122. 123. 125. 128. 131. 133. 137. 139. 139. + 140. 142. 144. 142. 144. 147. 150. 153. 154. 155. 155. 156. 159. + 159. 155. 153. 154. 153. 150. 145. 143. 140. 138. 145. 159. 170. + 175. 152. 170. 190. 200. 198. 189. 175. 164. 152. 147. 144. 138. + 134. 136. 116. 80. 48. 49. 46. 46. 50. 48. 52. 66. 59. 95. 67. 79. + 65. 57. 61. 49. 40. 47. 119. 164. 138. 135. 88. 71. 94. 141. 144. + 145. 151. 148. 160. 159. 155. 154. 153. 152. 151. 151. 151. 151. + 148. 149. 149. 149. 149. 148. 147. 146. 146. 146. 145. 144. 143. + 141. 140. 140. 133. 130. 135. 152. 173. 189. 195. 195. 194. 196. + 199. 203. 206. 207. 208. 208. 206. 206. 206. 206. 207. 208. 210. + 210. 209. 209. 208. 208. 209. 210. 212. 213. 81. 76. 73. 74. 78. 79. + 75. 71. 68. 63. 65. 76. 90. 105. 126. 144. 155. 160. 167. 170. 169. + 170. 172. 174. 175. 179. 180. 176. 169. 159. 144. 130. 102. 84. 73. + 80. 92. 96. 97. 99. 106. 127. 151. 126. 68. 51. 73. 84. 76. 87. 104. + 134. 80. 37. 68. 37. 65. 82. 62. 86. 97. 84. 110. 117. 87. 103. 139. + 104. 134. 118. 69. 68. 83. 79. 102. 81. 68. 64. 72. 29. 50. 83. 131. + 133. 149. 163. 187. 174. 97. 95. 91. 139. 186. 169. 74. 46. 49. 51. + 55. 60. 62. 62. 62. 62. 56. 48. 44. 75. 112. 103. 87. 100. 112. 117. + 123. 126. 125. 125. 127. 129. 133. 135. 138. 140. 140. 140. 142. + 144. 142. 144. 147. 150. 153. 154. 155. 155. 156. 160. 160. 155. + 152. 154. 154. 151. 147. 146. 144. 145. 155. 173. 191. 201. 168. + 178. 190. 197. 196. 188. 174. 163. 149. 147. 144. 135. 132. 134. + 108. 62. 45. 56. 48. 43. 55. 56. 54. 68. 58. 96. 63. 78. 62. 58. 66. + 55. 42. 46. 113. 163. 144. 136. 88. 83. 111. 153. 144. 144. 152. + 146. 160. 162. 154. 154. 153. 151. 151. 151. 151. 151. 148. 149. + 149. 149. 149. 148. 147. 146. 146. 146. 145. 144. 142. 141. 140. + 140. 133. 132. 138. 155. 176. 189. 195. 196. 195. 198. 201. 205. + 208. 209. 209. 208. 206. 205. 205. 206. 207. 208. 209. 210. 209. + 208. 208. 208. 209. 211. 213. 215. 76. 74. 71. 71. 72. 74. 74. 73. + 64. 61. 62. 72. 87. 105. 127. 143. 155. 159. 164. 168. 169. 170. + 171. 173. 173. 177. 178. 174. 169. 160. 143. 128. 102. 87. 73. 80. + 93. 89. 87. 101. 130. 146. 114. 108. 80. 69. 58. 72. 92. 141. 85. + 67. 72. 45. 58. 51. 77. 64. 79. 60. 86. 70. 100. 106. 86. 85. 121. + 109. 158. 111. 72. 84. 107. 97. 75. 94. 49. 43. 59. 41. 81. 137. + 160. 166. 139. 182. 201. 135. 93. 85. 96. 126. 199. 71. 38. 46. 49. + 47. 51. 50. 47. 59. 68. 61. 49. 51. 36. 58. 115. 102. 95. 94. 109. + 116. 120. 121. 122. 126. 128. 126. 130. 132. 136. 139. 141. 140. + 139. 137. 136. 140. 144. 145. 146. 149. 153. 154. 153. 153. 154. + 154. 153. 151. 148. 147. 146. 153. 153. 149. 158. 181. 198. 202. + 181. 175. 193. 207. 196. 188. 178. 152. 152. 131. 155. 145. 127. + 129. 85. 42. 50. 50. 43. 47. 44. 49. 67. 57. 71. 86. 63. 78. 64. 59. + 47. 50. 39. 37. 93. 157. 144. 147. 76. 107. 124. 143. 146. 142. 149. + 156. 154. 154. 153. 153. 152. 151. 149. 148. 147. 147. 145. 147. + 148. 147. 143. 141. 143. 145. 148. 147. 145. 143. 142. 140. 140. + 139. 134. 129. 137. 162. 184. 192. 194. 196. 198. 202. 206. 209. + 209. 208. 208. 208. 206. 207. 208. 209. 209. 209. 208. 208. 211. + 211. 211. 211. 211. 211. 211. 211. 76. 73. 71. 70. 71. 73. 73. 72. + 66. 62. 63. 73. 87. 105. 126. 143. 154. 158. 164. 167. 169. 170. + 171. 173. 174. 178. 178. 175. 170. 161. 144. 128. 104. 82. 72. 80. + 82. 82. 96. 115. 138. 121. 115. 117. 64. 54. 66. 99. 118. 117. 55. + 46. 68. 59. 59. 46. 72. 64. 79. 68. 82. 70. 99. 114. 74. 85. 124. + 107. 139. 120. 97. 58. 126. 71. 62. 59. 39. 37. 61. 71. 99. 139. + 161. 142. 187. 188. 183. 98. 93. 103. 92. 178. 104. 43. 49. 41. 52. + 49. 51. 50. 47. 58. 68. 62. 49. 51. 38. 55. 112. 102. 98. 92. 108. + 115. 120. 121. 123. 127. 129. 127. 130. 133. 136. 139. 141. 141. + 139. 138. 141. 143. 145. 145. 147. 150. 152. 153. 147. 148. 149. + 150. 151. 151. 151. 151. 147. 154. 154. 151. 161. 185. 203. 209. + 182. 173. 189. 207. 198. 185. 173. 154. 148. 144. 144. 137. 134. + 113. 67. 43. 49. 51. 45. 49. 44. 49. 68. 59. 76. 90. 67. 77. 65. 64. + 55. 52. 42. 38. 90. 156. 146. 142. 80. 115. 126. 143. 146. 142. 150. + 156. 154. 154. 154. 154. 153. 152. 151. 149. 148. 148. 146. 148. + 149. 147. 144. 142. 143. 145. 145. 146. 146. 146. 144. 141. 138. + 137. 134. 130. 139. 164. 185. 193. 195. 198. 199. 202. 207. 209. + 209. 208. 208. 208. 207. 207. 207. 208. 208. 209. 209. 209. 211. + 211. 211. 211. 211. 211. 211. 211. 75. 72. 69. 68. 69. 71. 70. 70. + 66. 63. 65. 73. 87. 104. 125. 143. 153. 157. 163. 167. 169. 170. + 171. 173. 176. 179. 180. 176. 171. 161. 144. 129. 108. 78. 72. 79. + 73. 84. 114. 129. 124. 109. 132. 106. 45. 72. 91. 100. 129. 83. 40. + 44. 69. 76. 68. 60. 65. 64. 74. 72. 71. 63. 84. 107. 59. 68. 110. + 119. 132. 113. 128. 91. 165. 71. 61. 35. 50. 71. 95. 105. 98. 144. + 127. 168. 187. 195. 124. 84. 94. 91. 159. 133. 44. 31. 50. 52. 55. + 50. 51. 50. 47. 58. 68. 65. 49. 50. 41. 51. 108. 100. 102. 88. 105. + 112. 119. 121. 124. 128. 130. 128. 131. 133. 136. 139. 141. 141. + 140. 140. 141. 139. 138. 140. 143. 145. 145. 146. 150. 150. 149. + 149. 148. 148. 147. 147. 148. 154. 155. 154. 166. 189. 208. 216. + 187. 178. 190. 206. 200. 185. 170. 155. 141. 153. 133. 134. 136. 88. + 47. 43. 48. 53. 48. 52. 46. 49. 70. 62. 75. 86. 67. 71. 62. 63. 60. + 47. 45. 38. 83. 156. 149. 135. 88. 125. 129. 144. 146. 143. 151. + 156. 154. 155. 155. 154. 154. 152. 151. 150. 149. 149. 148. 149. + 149. 148. 146. 144. 145. 146. 143. 144. 147. 148. 146. 142. 137. + 134. 133. 130. 140. 165. 186. 194. 196. 199. 200. 204. 208. 210. + 209. 208. 208. 208. 209. 208. 207. 207. 207. 208. 210. 211. 211. + 211. 211. 211. 211. 211. 211. 211. 72. 70. 67. 66. 67. 68. 68. 68. + 65. 63. 65. 73. 85. 101. 123. 141. 153. 157. 163. 167. 169. 170. + 172. 173. 177. 180. 180. 177. 172. 162. 145. 129. 111. 78. 72. 76. + 74. 102. 132. 125. 108. 101. 135. 97. 56. 89. 90. 97. 114. 54. 49. + 60. 67. 76. 69. 81. 68. 72. 76. 79. 66. 60. 70. 90. 79. 60. 69. 112. + 140. 106. 137. 142. 104. 34. 32. 45. 86. 121. 123. 94. 108. 128. + 155. 177. 194. 135. 98. 94. 94. 117. 177. 46. 44. 38. 60. 71. 55. + 48. 49. 50. 48. 59. 71. 70. 53. 48. 44. 47. 104. 96. 105. 84. 100. + 109. 117. 121. 125. 129. 131. 128. 131. 133. 136. 139. 140. 141. + 141. 141. 139. 135. 134. 138. 142. 142. 142. 144. 146. 145. 145. + 144. 144. 144. 144. 144. 149. 154. 156. 157. 167. 185. 200. 206. + 193. 194. 198. 199. 196. 189. 171. 150. 134. 149. 132. 141. 122. 60. + 42. 42. 48. 54. 50. 54. 47. 50. 71. 64. 74. 81. 69. 70. 62. 63. 65. + 42. 42. 36. 74. 154. 154. 127. 96. 130. 133. 146. 146. 144. 153. + 156. 153. 156. 154. 154. 153. 152. 150. 149. 148. 148. 150. 150. + 150. 149. 147. 146. 146. 146. 143. 144. 146. 146. 144. 141. 137. + 135. 131. 129. 140. 166. 187. 194. 197. 201. 203. 206. 209. 210. + 209. 208. 208. 208. 210. 209. 207. 206. 206. 208. 211. 212. 212. + 212. 212. 212. 212. 212. 212. 212. 69. 66. 64. 63. 65. 66. 67. 66. + 63. 62. 65. 72. 83. 99. 121. 141. 153. 157. 163. 168. 170. 171. 173. + 175. 178. 180. 181. 177. 171. 161. 144. 129. 108. 77. 69. 73. 84. + 121. 135. 103. 106. 93. 122. 100. 79. 65. 57. 113. 105. 47. 59. 66. + 58. 63. 59. 79. 74. 82. 88. 88. 78. 73. 73. 80. 100. 87. 51. 70. + 122. 110. 129. 143. 88. 40. 20. 82. 111. 149. 178. 167. 145. 159. + 197. 188. 156. 101. 93. 104. 121. 168. 88. 32. 43. 39. 82. 83. 53. + 44. 47. 50. 50. 59. 72. 74. 59. 45. 45. 45. 102. 89. 106. 81. 94. + 104. 114. 120. 125. 130. 131. 128. 130. 132. 134. 137. 139. 140. + 141. 141. 142. 137. 138. 143. 145. 141. 141. 144. 135. 136. 138. + 140. 143. 145. 146. 147. 150. 153. 155. 154. 157. 165. 173. 176. + 183. 195. 189. 172. 173. 178. 160. 133. 129. 135. 137. 146. 96. 42. + 49. 41. 49. 53. 50. 55. 49. 53. 72. 64. 77. 79. 77. 77. 70. 65. 72. + 45. 38. 35. 65. 149. 158. 122. 107. 130. 138. 147. 146. 145. 155. + 157. 153. 157. 152. 152. 151. 150. 148. 147. 146. 146. 151. 150. + 149. 148. 148. 148. 147. 146. 146. 145. 144. 143. 141. 140. 138. + 137. 128. 128. 141. 167. 187. 194. 197. 202. 205. 208. 210. 210. + 209. 208. 208. 209. 211. 209. 208. 206. 207. 209. 211. 213. 212. + 212. 212. 212. 212. 212. 212. 212. 64. 62. 60. 61. 63. 65. 66. 66. + 62. 62. 65. 73. 83. 98. 122. 142. 154. 158. 164. 169. 171. 173. 175. + 177. 177. 180. 180. 177. 171. 160. 143. 127. 104. 75. 66. 81. 101. + 124. 119. 86. 97. 114. 133. 85. 62. 45. 52. 104. 111. 60. 63. 64. + 57. 62. 54. 63. 66. 85. 102. 93. 91. 85. 85. 75. 68. 111. 83. 47. + 78. 101. 117. 128. 106. 68. 44. 112. 100. 111. 169. 202. 188. 208. + 201. 174. 97. 108. 91. 106. 173. 124. 41. 39. 37. 40. 72. 92. 51. + 42. 45. 52. 51. 59. 71. 73. 68. 41. 45. 45. 101. 79. 103. 79. 88. + 99. 111. 118. 124. 130. 130. 128. 129. 130. 132. 135. 137. 139. 140. + 141. 141. 137. 139. 143. 138. 127. 124. 129. 137. 139. 140. 142. + 142. 141. 140. 139. 142. 142. 141. 138. 136. 137. 140. 142. 151. + 164. 149. 126. 134. 145. 130. 109. 129. 130. 141. 130. 69. 37. 53. + 44. 50. 52. 47. 54. 52. 56. 73. 62. 78. 71. 78. 80. 71. 57. 74. 49. + 36. 37. 56. 139. 159. 120. 120. 130. 142. 148. 145. 146. 156. 157. + 153. 157. 151. 151. 150. 149. 148. 146. 146. 145. 151. 150. 148. + 148. 148. 148. 147. 145. 146. 145. 143. 141. 140. 139. 138. 138. + 127. 128. 143. 169. 188. 195. 199. 204. 208. 210. 211. 211. 209. + 208. 208. 209. 210. 209. 208. 208. 208. 210. 211. 212. 213. 213. + 213. 213. 213. 213. 213. 213. 60. 59. 57. 58. 62. 65. 66. 66. 62. + 62. 67. 75. 84. 100. 125. 146. 155. 160. 166. 170. 173. 175. 177. + 179. 177. 180. 180. 176. 170. 159. 142. 126. 103. 74. 71. 102. 122. + 111. 94. 89. 103. 138. 147. 73. 43. 51. 77. 64. 93. 67. 64. 65. 66. + 69. 59. 53. 54. 86. 121. 97. 104. 93. 98. 74. 52. 90. 105. 79. 75. + 91. 97. 115. 103. 94. 125. 163. 139. 131. 167. 191. 213. 202. 189. + 103. 105. 92. 110. 134. 163. 46. 56. 33. 48. 43. 45. 89. 52. 42. 46. + 53. 51. 56. 67. 69. 77. 37. 44. 46. 102. 71. 100. 78. 83. 95. 108. + 117. 123. 129. 130. 127. 127. 128. 130. 133. 135. 138. 139. 140. + 141. 139. 140. 140. 126. 106. 99. 104. 120. 122. 125. 127. 127. 125. + 122. 119. 119. 117. 114. 112. 111. 114. 119. 125. 127. 129. 108. 95. + 111. 118. 109. 107. 132. 138. 139. 95. 52. 44. 44. 49. 51. 51. 44. + 52. 53. 59. 73. 59. 82. 64. 75. 79. 67. 45. 73. 56. 40. 43. 49. 128. + 157. 121. 135. 133. 146. 149. 145. 147. 158. 157. 153. 158. 152. + 152. 151. 149. 148. 147. 146. 146. 151. 149. 147. 147. 148. 148. + 146. 144. 144. 144. 144. 143. 141. 139. 137. 136. 128. 130. 146. + 172. 191. 198. 202. 208. 210. 211. 212. 211. 209. 208. 208. 209. + 209. 209. 209. 210. 210. 210. 211. 211. 213. 213. 213. 213. 213. + 213. 213. 213. 58. 56. 56. 57. 61. 65. 66. 67. 63. 64. 69. 77. 86. + 103. 128. 149. 156. 160. 167. 171. 174. 176. 178. 180. 176. 179. + 179. 175. 169. 158. 141. 125. 105. 76. 78. 122. 137. 98. 77. 100. + 134. 134. 136. 87. 55. 57. 87. 37. 52. 57. 62. 68. 71. 70. 63. 50. + 52. 95. 142. 106. 115. 99. 109. 78. 91. 53. 85. 121. 115. 97. 72. + 91. 80. 79. 137. 121. 121. 156. 196. 204. 210. 195. 136. 93. 99. + 110. 104. 191. 93. 38. 45. 45. 62. 40. 39. 76. 54. 43. 47. 54. 51. + 54. 63. 65. 82. 35. 44. 48. 103. 65. 98. 77. 80. 93. 107. 116. 123. + 128. 129. 126. 126. 127. 129. 132. 134. 137. 138. 139. 147. 145. + 146. 142. 121. 94. 85. 90. 78. 83. 91. 99. 105. 107. 107. 107. 96. + 93. 91. 92. 95. 102. 114. 123. 126. 116. 92. 92. 114. 114. 109. 126. + 135. 150. 134. 65. 45. 52. 33. 54. 52. 50. 42. 51. 54. 61. 74. 57. + 90. 66. 78. 82. 68. 42. 78. 67. 44. 48. 46. 120. 154. 123. 145. 137. + 147. 150. 145. 148. 158. 158. 153. 158. 153. 153. 152. 151. 149. + 148. 147. 147. 151. 148. 146. 146. 148. 148. 146. 143. 141. 143. + 145. 146. 144. 140. 136. 133. 129. 132. 148. 175. 194. 200. 205. + 211. 211. 212. 213. 211. 209. 208. 208. 209. 208. 209. 210. 211. + 211. 211. 211. 210. 213. 213. 213. 213. 213. 213. 213. 213. 54. 54. + 55. 57. 59. 62. 64. 66. 64. 61. 72. 86. 91. 107. 130. 142. 155. 160. + 168. 173. 175. 176. 176. 177. 178. 178. 182. 177. 164. 159. 145. + 121. 107. 70. 129. 141. 96. 78. 79. 122. 147. 138. 118. 79. 52. 82. + 54. 50. 33. 73. 56. 67. 74. 60. 79. 60. 57. 93. 148. 116. 107. 94. + 93. 104. 102. 95. 80. 105. 135. 94. 54. 78. 61. 93. 129. 136. 142. + 137. 198. 218. 208. 188. 104. 101. 79. 126. 182. 131. 44. 45. 47. + 48. 45. 43. 50. 59. 60. 48. 45. 54. 61. 58. 58. 64. 79. 61. 38. 48. + 101. 64. 97. 81. 80. 91. 106. 116. 120. 121. 124. 127. 125. 126. + 128. 131. 134. 136. 138. 140. 147. 148. 148. 142. 133. 125. 122. + 121. 110. 106. 103. 106. 112. 118. 121. 121. 117. 117. 116. 116. + 118. 122. 127. 131. 137. 154. 136. 120. 138. 140. 130. 141. 150. + 143. 95. 46. 42. 49. 48. 53. 53. 47. 40. 55. 61. 78. 51. 64. 83. 68. + 71. 84. 63. 49. 72. 77. 42. 47. 40. 95. 161. 135. 148. 138. 150. + 146. 146. 151. 154. 153. 153. 155. 152. 153. 153. 153. 153. 152. + 151. 150. 148. 148. 147. 147. 147. 147. 146. 146. 146. 145. 144. + 144. 143. 140. 135. 132. 124. 130. 156. 183. 193. 201. 209. 209. + 212. 211. 210. 209. 209. 209. 209. 209. 210. 210. 209. 210. 211. + 213. 215. 217. 213. 213. 213. 213. 213. 213. 213. 214. 54. 55. 56. + 57. 59. 62. 64. 65. 62. 60. 73. 86. 91. 106. 130. 142. 155. 160. + 167. 173. 175. 176. 176. 177. 180. 179. 182. 175. 162. 156. 143. + 119. 102. 141. 139. 84. 84. 96. 85. 125. 133. 120. 118. 75. 61. 64. + 69. 53. 49. 56. 50. 53. 74. 60. 67. 82. 52. 87. 158. 121. 76. 89. + 94. 107. 111. 93. 95. 91. 74. 89. 101. 79. 92. 119. 159. 141. 134. + 122. 162. 219. 208. 118. 106. 92. 126. 175. 161. 65. 48. 49. 51. 52. + 47. 43. 48. 56. 59. 48. 44. 52. 58. 57. 58. 63. 73. 61. 41. 48. 93. + 59. 91. 80. 76. 87. 102. 113. 117. 119. 121. 124. 125. 126. 128. + 131. 134. 136. 138. 139. 145. 147. 147. 144. 138. 132. 128. 126. + 124. 123. 122. 121. 121. 123. 127. 130. 139. 146. 155. 160. 163. + 169. 179. 187. 180. 180. 153. 132. 142. 148. 141. 144. 145. 115. 70. + 43. 43. 45. 46. 53. 48. 44. 47. 53. 59. 66. 49. 67. 88. 68. 77. 82. + 61. 53. 66. 79. 44. 48. 42. 95. 162. 139. 150. 141. 151. 147. 147. + 152. 155. 153. 153. 155. 152. 153. 153. 153. 153. 152. 151. 150. + 148. 148. 148. 147. 147. 147. 146. 146. 146. 145. 144. 144. 143. + 140. 135. 131. 124. 131. 158. 185. 195. 203. 211. 210. 212. 212. + 211. 210. 209. 209. 210. 210. 210. 210. 211. 211. 212. 214. 215. + 216. 213. 213. 213. 213. 213. 213. 212. 212. 55. 55. 56. 57. 59. 61. + 63. 64. 59. 59. 74. 87. 90. 105. 129. 142. 153. 159. 167. 172. 175. + 176. 177. 178. 181. 180. 182. 176. 163. 159. 148. 125. 126. 148. + 109. 65. 81. 88. 97. 147. 119. 104. 118. 75. 75. 61. 103. 66. 57. + 38. 45. 46. 86. 63. 57. 99. 55. 95. 168. 126. 54. 72. 89. 101. 110. + 104. 92. 76. 64. 69. 88. 105. 118. 130. 166. 138. 129. 127. 149. + 215. 145. 99. 112. 115. 180. 171. 87. 48. 50. 51. 54. 54. 48. 42. + 44. 51. 57. 48. 44. 51. 56. 56. 58. 63. 68. 61. 46. 48. 83. 55. 85. + 79. 70. 81. 96. 108. 114. 116. 118. 119. 124. 125. 126. 128. 131. + 133. 134. 135. 143. 144. 145. 146. 145. 141. 135. 131. 127. 130. + 130. 127. 123. 123. 128. 133. 143. 154. 167. 173. 173. 174. 181. + 188. 196. 181. 153. 134. 137. 149. 148. 140. 134. 80. 43. 43. 46. + 44. 48. 53. 42. 40. 55. 50. 59. 52. 48. 70. 93. 67. 84. 79. 61. 60. + 58. 84. 46. 48. 44. 94. 161. 144. 152. 145. 153. 149. 148. 153. 156. + 154. 154. 156. 153. 153. 153. 153. 153. 152. 151. 151. 149. 148. + 148. 148. 147. 147. 146. 146. 145. 144. 143. 143. 142. 139. 134. + 130. 124. 132. 160. 188. 198. 206. 213. 211. 212. 212. 211. 210. + 210. 210. 210. 211. 211. 212. 213. 213. 214. 214. 214. 214. 213. + 212. 212. 211. 211. 210. 210. 210. 55. 55. 56. 56. 58. 60. 61. 62. + 56. 58. 75. 89. 90. 103. 128. 141. 152. 158. 166. 172. 175. 176. + 177. 178. 180. 179. 182. 177. 168. 166. 157. 136. 139. 91. 68. 81. + 73. 87. 134. 146. 107. 101. 106. 72. 73. 78. 131. 69. 49. 37. 42. + 56. 104. 66. 61. 97. 66. 123. 161. 122. 74. 55. 81. 88. 95. 107. + 104. 91. 80. 72. 82. 108. 136. 133. 149. 136. 124. 144. 174. 182. + 94. 118. 128. 180. 173. 109. 41. 61. 48. 50. 54. 55. 49. 42. 42. 48. + 57. 50. 47. 52. 56. 57. 59. 64. 69. 64. 49. 49. 78. 61. 81. 78. 66. + 76. 91. 103. 110. 114. 115. 116. 120. 121. 122. 124. 127. 129. 130. + 131. 141. 141. 142. 146. 148. 146. 139. 133. 125. 126. 127. 125. + 123. 124. 128. 131. 134. 143. 153. 158. 156. 153. 152. 153. 165. + 151. 139. 132. 134. 149. 151. 136. 112. 59. 36. 46. 47. 48. 54. 50. + 45. 39. 59. 47. 61. 46. 49. 72. 94. 66. 89. 75. 62. 67. 54. 91. 49. + 47. 46. 90. 159. 149. 153. 148. 154. 150. 150. 154. 157. 155. 155. + 157. 153. 153. 154. 154. 153. 153. 152. 151. 150. 149. 149. 148. + 147. 147. 146. 146. 145. 144. 143. 142. 141. 138. 133. 129. 124. + 132. 162. 192. 203. 209. 215. 213. 213. 212. 211. 211. 211. 211. + 212. 212. 212. 213. 214. 215. 215. 214. 212. 211. 210. 210. 209. + 208. 208. 207. 206. 206. 55. 54. 55. 55. 56. 57. 59. 60. 53. 58. 77. + 90. 89. 100. 125. 140. 150. 156. 164. 171. 175. 176. 178. 179. 180. + 180. 183. 178. 168. 167. 158. 136. 113. 67. 63. 76. 69. 119. 163. + 110. 103. 106. 86. 64. 57. 103. 133. 55. 40. 51. 41. 71. 106. 63. + 76. 87. 73. 150. 139. 108. 117. 57. 85. 89. 73. 87. 126. 118. 80. + 106. 131. 90. 145. 148. 144. 148. 113. 147. 202. 137. 120. 125. 174. + 206. 109. 63. 57. 49. 48. 51. 56. 58. 53. 46. 46. 52. 55. 52. 51. + 55. 58. 59. 61. 64. 73. 67. 52. 49. 75. 71. 80. 76. 64. 73. 86. 98. + 106. 110. 112. 113. 118. 119. 121. 123. 126. 128. 129. 130. 139. + 139. 141. 144. 147. 145. 138. 132. 132. 129. 126. 126. 128. 129. + 129. 127. 131. 135. 141. 148. 152. 151. 146. 142. 133. 133. 139. + 143. 145. 152. 147. 127. 82. 51. 42. 48. 44. 51. 57. 45. 53. 42. 58. + 47. 64. 48. 52. 76. 90. 66. 87. 74. 67. 70. 55. 96. 51. 45. 48. 86. + 156. 153. 152. 149. 155. 151. 150. 155. 157. 155. 155. 156. 153. + 154. 154. 154. 154. 153. 152. 151. 151. 150. 150. 149. 148. 147. + 146. 146. 145. 144. 143. 142. 140. 137. 131. 127. 122. 132. 164. + 195. 206. 212. 217. 214. 213. 212. 212. 212. 212. 212. 213. 214. + 213. 214. 215. 215. 214. 213. 211. 209. 207. 207. 206. 206. 205. + 205. 204. 204. 53. 53. 53. 53. 54. 55. 56. 56. 52. 59. 80. 92. 88. + 97. 122. 137. 149. 155. 163. 170. 175. 177. 178. 180. 182. 181. 183. + 177. 165. 161. 149. 126. 95. 78. 66. 66. 98. 141. 135. 95. 111. 112. + 73. 60. 53. 126. 118. 42. 42. 61. 42. 83. 87. 56. 79. 81. 80. 165. + 121. 95. 134. 87. 101. 108. 61. 71. 98. 113. 113. 123. 128. 112. + 124. 153. 144. 155. 107. 148. 215. 127. 151. 156. 216. 140. 64. 50. + 56. 52. 51. 54. 59. 61. 57. 50. 51. 57. 53. 53. 55. 57. 59. 61. 62. + 63. 72. 68. 55. 50. 70. 77. 78. 76. 64. 70. 80. 91. 100. 106. 108. + 109. 117. 118. 121. 123. 126. 129. 131. 132. 135. 137. 139. 142. + 143. 142. 138. 134. 137. 132. 127. 127. 129. 129. 125. 121. 126. + 125. 126. 131. 137. 138. 133. 127. 127. 139. 147. 150. 154. 147. + 125. 103. 57. 50. 48. 45. 42. 50. 53. 44. 61. 48. 55. 51. 61. 53. + 53. 82. 83. 71. 82. 75. 73. 68. 57. 95. 56. 45. 51. 82. 153. 156. + 151. 150. 155. 151. 150. 155. 157. 155. 154. 156. 154. 154. 155. + 155. 154. 153. 152. 152. 151. 151. 150. 149. 148. 147. 146. 146. + 145. 143. 142. 141. 139. 136. 130. 126. 121. 131. 165. 198. 209. + 215. 218. 214. 213. 213. 212. 212. 213. 213. 214. 215. 215. 215. + 214. 213. 212. 210. 209. 208. 205. 205. 205. 205. 205. 205. 205. + 205. 52. 52. 51. 51. 51. 52. 53. 54. 51. 60. 82. 94. 87. 94. 119. + 135. 148. 154. 163. 170. 174. 177. 179. 180. 182. 181. 184. 177. + 164. 158. 145. 121. 100. 78. 66. 71. 123. 139. 97. 105. 113. 101. + 64. 57. 65. 136. 98. 41. 48. 51. 49. 97. 65. 52. 62. 76. 98. 173. + 126. 92. 104. 127. 111. 124. 75. 74. 63. 97. 147. 124. 97. 131. 91. + 136. 130. 138. 114. 162. 205. 146. 160. 190. 170. 65. 52. 48. 45. + 62. 53. 55. 59. 61. 55. 49. 51. 57. 48. 52. 56. 59. 60. 61. 61. 60. + 65. 66. 58. 49. 62. 75. 73. 78. 64. 68. 75. 84. 94. 100. 104. 105. + 113. 114. 117. 120. 124. 127. 130. 131. 131. 134. 138. 140. 140. + 140. 139. 139. 135. 133. 131. 129. 128. 126. 125. 123. 122. 120. + 119. 119. 121. 122. 121. 120. 137. 152. 147. 142. 151. 135. 96. 75. + 47. 51. 46. 42. 46. 48. 48. 52. 65. 54. 52. 56. 54. 55. 52. 90. 79. + 80. 77. 78. 78. 61. 59. 90. 61. 48. 55. 81. 152. 160. 151. 152. 155. + 151. 150. 154. 156. 154. 153. 155. 154. 154. 155. 155. 154. 154. + 153. 152. 152. 152. 151. 150. 148. 147. 146. 146. 144. 143. 142. + 141. 139. 135. 129. 125. 119. 130. 165. 199. 211. 216. 219. 213. + 213. 213. 213. 213. 213. 214. 215. 216. 216. 215. 213. 211. 209. + 208. 207. 207. 205. 205. 206. 207. 207. 208. 209. 209. 51. 51. 50. + 50. 50. 50. 51. 52. 51. 61. 84. 95. 86. 92. 117. 133. 147. 154. 162. + 170. 174. 177. 179. 180. 180. 180. 184. 179. 166. 161. 147. 123. + 101. 71. 75. 72. 113. 139. 97. 106. 104. 78. 53. 49. 75. 133. 82. + 43. 50. 35. 57. 111. 54. 52. 40. 71. 120. 180. 142. 96. 64. 152. + 111. 129. 102. 79. 74. 102. 131. 135. 119. 105. 76. 121. 112. 114. + 124. 177. 182. 158. 181. 182. 72. 51. 42. 50. 68. 42. 52. 53. 56. + 57. 51. 45. 47. 54. 45. 51. 56. 59. 60. 60. 59. 57. 57. 64. 60. 49. + 54. 71. 69. 79. 63. 66. 71. 80. 89. 96. 101. 102. 107. 109. 112. + 116. 120. 123. 126. 128. 128. 133. 138. 140. 139. 139. 141. 144. + 131. 134. 137. 135. 131. 130. 132. 135. 127. 128. 129. 128. 129. + 132. 139. 144. 148. 161. 142. 131. 147. 128. 81. 62. 48. 53. 42. 41. + 53. 48. 45. 63. 64. 58. 52. 61. 47. 55. 50. 96. 77. 86. 74. 80. 82. + 56. 60. 85. 65. 50. 58. 81. 152. 163. 152. 153. 155. 151. 150. 153. + 155. 153. 152. 154. 154. 155. 155. 155. 155. 154. 153. 152. 153. + 152. 151. 150. 148. 147. 146. 146. 144. 143. 141. 140. 138. 134. + 129. 125. 117. 130. 165. 200. 212. 216. 219. 213. 213. 213. 213. + 213. 214. 215. 216. 216. 217. 215. 212. 209. 207. 206. 206. 206. + 206. 207. 207. 209. 210. 211. 212. 212. 52. 51. 50. 50. 50. 50. 49. + 48. 47. 75. 99. 102. 99. 107. 122. 131. 140. 148. 159. 169. 174. + 176. 176. 177. 178. 181. 180. 176. 171. 161. 145. 130. 99. 78. 64. + 74. 119. 131. 99. 98. 87. 81. 57. 52. 78. 113. 56. 51. 45. 35. 69. + 81. 63. 56. 51. 54. 127. 171. 129. 131. 82. 115. 142. 130. 102. 110. + 124. 85. 94. 121. 128. 97. 67. 129. 128. 114. 126. 173. 180. 187. + 204. 106. 43. 51. 60. 47. 45. 55. 53. 55. 59. 60. 54. 47. 49. 55. + 50. 55. 56. 53. 54. 59. 59. 55. 57. 65. 64. 54. 52. 62. 69. 67. 65. + 63. 66. 75. 82. 87. 96. 106. 103. 108. 114. 118. 125. 131. 130. 125. + 134. 134. 136. 138. 140. 140. 137. 135. 139. 136. 132. 132. 135. + 140. 143. 145. 145. 152. 156. 153. 151. 153. 154. 153. 154. 152. + 139. 144. 145. 96. 56. 71. 52. 47. 42. 42. 46. 52. 55. 56. 65. 49. + 50. 50. 50. 45. 51. 94. 83. 72. 86. 80. 65. 65. 67. 79. 68. 48. 60. + 70. 144. 170. 154. 157. 145. 148. 153. 156. 156. 155. 155. 155. 154. + 154. 154. 153. 153. 153. 152. 152. 152. 151. 149. 149. 149. 147. + 144. 142. 143. 142. 141. 140. 138. 134. 127. 122. 120. 125. 169. + 198. 210. 220. 216. 220. 214. 214. 214. 215. 215. 216. 216. 217. + 212. 211. 211. 210. 210. 210. 211. 212. 208. 209. 210. 210. 209. + 209. 210. 211. 51. 50. 50. 50. 50. 50. 49. 49. 52. 80. 103. 104. 99. + 107. 123. 133. 140. 148. 160. 169. 174. 176. 176. 176. 177. 180. + 180. 176. 170. 160. 144. 129. 103. 80. 66. 72. 111. 126. 102. 105. + 87. 80. 65. 81. 71. 97. 60. 46. 43. 45. 80. 80. 58. 61. 60. 57. 120. + 151. 133. 111. 110. 107. 145. 124. 113. 110. 103. 76. 93. 116. 132. + 98. 58. 120. 97. 125. 111. 210. 232. 196. 126. 72. 42. 52. 58. 52. + 51. 52. 47. 50. 55. 57. 52. 46. 50. 57. 51. 55. 55. 50. 49. 54. 58. + 58. 56. 63. 62. 53. 50. 59. 65. 64. 66. 60. 62. 72. 77. 78. 89. 103. + 107. 112. 116. 117. 120. 126. 129. 127. 134. 135. 136. 138. 140. + 140. 139. 138. 140. 142. 143. 143. 142. 144. 149. 153. 157. 163. + 165. 161. 157. 158. 157. 155. 158. 149. 144. 149. 128. 70. 44. 68. + 48. 44. 41. 43. 48. 54. 57. 59. 65. 51. 54. 52. 52. 46. 54. 99. 87. + 76. 90. 85. 70. 72. 73. 85. 66. 50. 57. 68. 144. 171. 157. 160. 143. + 149. 155. 158. 157. 155. 155. 156. 154. 154. 153. 153. 153. 152. + 152. 152. 153. 151. 150. 149. 149. 148. 145. 142. 143. 142. 141. + 140. 138. 133. 127. 122. 118. 125. 171. 200. 211. 221. 216. 219. + 215. 215. 215. 214. 214. 214. 214. 214. 213. 212. 211. 211. 210. + 211. 211. 211. 214. 214. 213. 212. 209. 207. 207. 207. 49. 49. 49. + 49. 50. 50. 50. 50. 59. 86. 107. 106. 99. 106. 123. 135. 141. 149. + 160. 169. 174. 176. 176. 176. 176. 179. 179. 175. 169. 159. 143. + 128. 104. 81. 68. 68. 98. 117. 103. 110. 83. 79. 72. 104. 73. 76. + 63. 44. 37. 48. 84. 74. 48. 58. 62. 58. 107. 134. 121. 95. 122. 106. + 139. 127. 108. 115. 103. 81. 80. 82. 129. 116. 110. 131. 77. 127. + 100. 171. 212. 135. 60. 47. 46. 51. 50. 53. 56. 49. 47. 50. 56. 57. + 51. 45. 49. 58. 50. 54. 54. 47. 44. 48. 56. 61. 54. 61. 60. 52. 49. + 55. 60. 60. 66. 56. 57. 69. 71. 66. 76. 94. 96. 103. 109. 110. 114. + 124. 132. 135. 133. 134. 135. 136. 138. 139. 140. 141. 140. 147. + 154. 154. 151. 150. 155. 160. 167. 172. 172. 167. 163. 162. 160. + 156. 160. 145. 151. 151. 103. 45. 40. 67. 43. 42. 42. 44. 50. 55. + 59. 61. 63. 53. 58. 55. 53. 48. 58. 104. 86. 75. 89. 83. 69. 73. 74. + 84. 67. 57. 56. 65. 144. 169. 158. 161. 140. 148. 156. 159. 156. + 153. 153. 155. 153. 153. 153. 152. 152. 152. 151. 151. 153. 152. + 150. 150. 149. 148. 145. 143. 142. 141. 140. 140. 137. 133. 126. + 121. 115. 127. 175. 204. 213. 221. 216. 218. 215. 215. 214. 214. + 213. 212. 211. 211. 214. 213. 212. 211. 211. 210. 211. 211. 205. + 204. 204. 204. 203. 203. 203. 202. 47. 48. 49. 49. 49. 49. 50. 52. + 63. 89. 108. 105. 98. 105. 123. 135. 141. 149. 160. 169. 174. 175. + 176. 176. 176. 178. 178. 174. 168. 159. 142. 127. 102. 79. 69. 66. + 87. 108. 101. 105. 76. 76. 68. 94. 95. 62. 62. 48. 37. 46. 81. 73. + 45. 52. 61. 65. 97. 128. 99. 86. 100. 104. 121. 136. 115. 129. 113. + 99. 85. 66. 130. 130. 123. 135. 75. 96. 105. 131. 191. 87. 57. 50. + 51. 50. 44. 49. 54. 49. 54. 57. 62. 61. 52. 44. 48. 57. 47. 52. 54. + 49. 43. 44. 52. 59. 54. 59. 60. 53. 50. 54. 57. 58. 66. 54. 56. 69. + 68. 56. 60. 78. 82. 92. 100. 103. 107. 117. 127. 133. 130. 131. 133. + 134. 136. 138. 141. 144. 141. 148. 156. 160. 159. 158. 159. 162. + 168. 172. 172. 168. 165. 165. 163. 158. 156. 145. 157. 143. 79. 40. + 53. 67. 43. 43. 44. 47. 51. 56. 59. 61. 60. 53. 60. 56. 52. 49. 61. + 108. 87. 77. 90. 81. 68. 73. 72. 79. 69. 67. 56. 63. 145. 166. 158. + 160. 138. 147. 156. 158. 155. 151. 152. 154. 152. 152. 152. 152. + 151. 151. 151. 150. 153. 151. 150. 149. 149. 148. 145. 142. 142. + 141. 140. 139. 137. 132. 125. 121. 114. 130. 181. 208. 214. 222. + 215. 216. 213. 212. 212. 212. 212. 212. 212. 212. 215. 214. 213. + 211. 210. 210. 210. 210. 209. 208. 208. 208. 209. 209. 208. 206. 46. + 48. 50. 50. 48. 48. 50. 52. 62. 86. 103. 101. 96. 106. 123. 134. + 142. 150. 160. 169. 174. 175. 175. 175. 176. 178. 178. 174. 168. + 159. 142. 127. 101. 77. 73. 70. 85. 106. 99. 95. 66. 72. 59. 64. + 122. 62. 57. 56. 48. 44. 77. 79. 52. 51. 60. 74. 99. 126. 96. 67. + 71. 78. 100. 130. 140. 138. 115. 115. 114. 90. 137. 124. 112. 154. + 87. 76. 106. 124. 160. 70. 78. 56. 49. 53. 49. 49. 52. 49. 55. 59. + 64. 62. 52. 44. 49. 59. 44. 49. 54. 53. 47. 44. 48. 55. 54. 59. 60. + 56. 52. 54. 57. 58. 65. 55. 57. 70. 68. 53. 50. 59. 72. 83. 93. 97. + 101. 109. 117. 121. 128. 130. 133. 135. 136. 139. 144. 148. 145. + 148. 154. 160. 165. 166. 164. 162. 165. 168. 169. 167. 167. 169. + 167. 162. 150. 148. 157. 124. 58. 46. 66. 58. 48. 48. 49. 50. 52. + 55. 59. 61. 56. 52. 59. 54. 51. 51. 63. 108. 92. 83. 94. 84. 70. 76. + 75. 79. 66. 73. 53. 61. 148. 166. 161. 162. 141. 148. 156. 159. 156. + 154. 154. 155. 152. 151. 151. 151. 150. 150. 150. 150. 152. 151. + 149. 149. 148. 147. 144. 142. 141. 140. 139. 138. 136. 131. 125. + 120. 116. 136. 189. 212. 215. 222. 215. 215. 209. 209. 210. 211. + 212. 213. 214. 214. 215. 214. 212. 211. 209. 208. 208. 208. 208. + 207. 206. 207. 207. 205. 200. 196. 45. 48. 51. 50. 47. 46. 48. 51. + 58. 79. 96. 97. 97. 109. 124. 132. 143. 150. 161. 169. 174. 175. + 175. 174. 176. 179. 179. 175. 169. 159. 143. 128. 103. 76. 74. 75. + 87. 109. 97. 80. 56. 65. 54. 48. 129. 71. 51. 62. 55. 43. 71. 76. + 52. 48. 54. 67. 109. 124. 115. 54. 58. 51. 87. 107. 131. 129. 125. + 127. 126. 102. 132. 121. 136. 161. 89. 95. 99. 95. 75. 61. 77. 51. + 45. 58. 58. 53. 52. 49. 52. 57. 62. 61. 51. 44. 52. 64. 45. 48. 54. + 58. 53. 47. 47. 52. 53. 57. 59. 58. 55. 54. 56. 59. 63. 57. 59. 68. + 69. 59. 49. 47. 54. 65. 78. 86. 96. 108. 118. 121. 123. 128. 133. + 136. 137. 139. 144. 149. 148. 149. 153. 159. 166. 169. 168. 165. + 165. 167. 168. 166. 168. 171. 169. 163. 146. 151. 151. 104. 45. 49. + 67. 47. 53. 53. 54. 53. 53. 55. 60. 63. 54. 50. 57. 51. 51. 54. 66. + 108. 91. 83. 94. 82. 69. 77. 75. 76. 60. 77. 51. 60. 153. 168. 164. + 165. 146. 149. 154. 157. 157. 156. 156. 156. 151. 151. 150. 150. + 150. 149. 149. 149. 151. 149. 148. 147. 147. 146. 143. 140. 140. + 139. 138. 137. 135. 130. 124. 119. 120. 143. 196. 216. 216. 222. + 216. 215. 208. 209. 210. 211. 213. 214. 215. 216. 215. 214. 212. + 209. 208. 206. 206. 205. 201. 200. 200. 202. 202. 197. 189. 182. 46. + 49. 52. 50. 46. 44. 47. 50. 55. 73. 89. 93. 100. 115. 127. 132. 143. + 150. 161. 169. 174. 174. 174. 174. 177. 180. 180. 176. 170. 160. + 144. 129. 105. 72. 70. 73. 86. 109. 92. 64. 50. 56. 59. 62. 109. 81. + 45. 64. 60. 48. 70. 67. 47. 49. 48. 48. 113. 130. 129. 74. 54. 59. + 83. 90. 109. 109. 129. 129. 129. 112. 127. 121. 141. 139. 105. 97. + 94. 89. 49. 72. 60. 46. 48. 58. 57. 54. 54. 49. 54. 59. 65. 63. 52. + 45. 53. 66. 49. 49. 54. 59. 57. 50. 48. 51. 51. 54. 58. 59. 56. 54. + 56. 59. 62. 59. 58. 63. 70. 68. 56. 44. 42. 50. 60. 70. 84. 101. + 112. 115. 113. 120. 127. 131. 132. 134. 139. 143. 144. 147. 151. + 156. 160. 163. 167. 169. 168. 169. 168. 165. 166. 168. 164. 157. + 144. 149. 141. 92. 43. 47. 63. 49. 56. 57. 56. 54. 54. 56. 62. 68. + 54. 50. 55. 50. 53. 59. 69. 108. 88. 80. 91. 79. 69. 80. 78. 77. 61. + 85. 52. 60. 155. 165. 162. 161. 145. 145. 145. 148. 152. 154. 152. + 150. 150. 150. 150. 149. 149. 149. 148. 148. 149. 148. 146. 146. + 146. 144. 141. 139. 140. 139. 138. 137. 134. 130. 123. 118. 125. + 149. 203. 219. 216. 222. 216. 215. 210. 210. 211. 212. 213. 214. + 215. 215. 214. 213. 211. 208. 206. 204. 203. 203. 205. 201. 197. + 192. 183. 169. 151. 138. 46. 50. 53. 50. 46. 43. 46. 50. 52. 69. 84. + 92. 103. 119. 130. 132. 143. 151. 161. 169. 174. 174. 174. 174. 178. + 181. 180. 176. 171. 161. 145. 130. 104. 67. 64. 67. 81. 106. 87. 52. + 47. 50. 66. 85. 85. 87. 43. 63. 66. 59. 77. 64. 46. 56. 51. 37. 110. + 140. 128. 108. 49. 89. 82. 87. 113. 95. 117. 122. 144. 143. 134. + 113. 135. 150. 167. 73. 84. 116. 88. 61. 50. 49. 55. 56. 48. 50. 55. + 50. 61. 66. 71. 67. 54. 46. 53. 66. 53. 50. 52. 58. 58. 52. 50. 52. + 49. 52. 56. 58. 56. 54. 55. 59. 61. 60. 57. 59. 69. 75. 64. 46. 49. + 52. 54. 59. 70. 84. 93. 95. 103. 111. 120. 124. 125. 127. 131. 136. + 137. 143. 149. 151. 151. 155. 163. 170. 170. 170. 167. 163. 162. + 162. 157. 149. 143. 146. 134. 90. 48. 46. 60. 58. 57. 58. 57. 55. + 54. 58. 65. 71. 55. 50. 54. 49. 55. 62. 71. 108. 90. 83. 94. 83. 75. + 87. 86. 85. 67. 94. 56. 62. 156. 161. 156. 153. 141. 138. 136. 139. + 145. 148. 147. 143. 150. 150. 149. 149. 149. 148. 148. 148. 148. + 147. 145. 145. 145. 143. 140. 138. 139. 138. 137. 136. 134. 129. + 123. 118. 128. 153. 206. 221. 216. 222. 217. 216. 212. 213. 213. + 213. 213. 213. 214. 214. 214. 212. 210. 207. 205. 203. 202. 202. + 195. 186. 171. 153. 130. 101. 70. 50. 43. 45. 47. 46. 44. 43. 45. + 48. 50. 60. 77. 93. 101. 109. 122. 136. 147. 154. 163. 168. 170. + 171. 173. 175. 173. 178. 180. 176. 169. 158. 143. 129. 100. 61. 55. + 78. 122. 126. 78. 116. 49. 39. 81. 88. 71. 71. 59. 64. 54. 73. 71. + 48. 58. 41. 55. 41. 77. 171. 122. 118. 62. 82. 72. 72. 91. 110. 114. + 84. 118. 138. 98. 127. 125. 166. 142. 127. 137. 134. 118. 74. 45. + 47. 48. 48. 53. 55. 55. 54. 53. 71. 69. 71. 40. 49. 52. 72. 53. 49. + 51. 56. 56. 50. 49. 52. 41. 47. 54. 57. 58. 58. 61. 65. 64. 65. 61. + 59. 64. 72. 72. 65. 58. 54. 54. 59. 60. 58. 61. 68. 73. 81. 92. 99. + 104. 111. 120. 127. 133. 136. 141. 145. 148. 151. 154. 157. 167. + 161. 156. 155. 158. 156. 149. 142. 138. 142. 124. 85. 55. 49. 51. + 48. 50. 59. 60. 52. 51. 59. 64. 61. 62. 54. 50. 53. 53. 58. 79. 103. + 97. 87. 89. 85. 71. 81. 92. 78. 70. 81. 64. 79. 151. 164. 163. 149. + 139. 126. 120. 129. 137. 137. 137. 142. 145. 146. 146. 147. 149. + 151. 152. 154. 149. 149. 148. 147. 145. 143. 141. 140. 139. 136. + 135. 137. 134. 124. 117. 115. 135. 176. 207. 217. 220. 216. 211. + 215. 208. 212. 213. 209. 209. 212. 214. 212. 204. 210. 211. 205. + 199. 197. 192. 184. 171. 145. 106. 72. 52. 44. 42. 41. 47. 49. 50. + 48. 45. 42. 42. 44. 48. 59. 76. 89. 94. 100. 115. 131. 146. 154. + 163. 169. 171. 171. 173. 175. 178. 180. 179. 174. 168. 156. 137. + 120. 90. 77. 79. 148. 189. 93. 114. 133. 49. 38. 65. 80. 67. 60. 57. + 60. 59. 63. 55. 47. 48. 39. 51. 37. 74. 145. 136. 145. 82. 102. 95. + 44. 78. 121. 153. 99. 82. 114. 105. 118. 153. 148. 142. 138. 137. + 162. 169. 120. 52. 50. 53. 63. 33. 48. 53. 49. 60. 78. 75. 73. 42. + 49. 53. 70. 51. 48. 50. 54. 54. 49. 48. 51. 46. 47. 50. 55. 59. 61. + 61. 60. 60. 60. 57. 55. 61. 72. 75. 73. 64. 64. 70. 79. 85. 86. 90. + 96. 97. 103. 109. 112. 112. 114. 120. 124. 135. 139. 145. 149. 151. + 153. 156. 158. 160. 157. 154. 154. 154. 151. 144. 139. 130. 135. + 116. 72. 40. 42. 61. 73. 60. 59. 57. 57. 63. 66. 62. 54. 59. 51. 49. + 52. 53. 58. 77. 99. 94. 86. 91. 89. 74. 81. 90. 77. 69. 76. 65. 76. + 157. 161. 162. 144. 127. 119. 116. 120. 126. 129. 131. 133. 137. + 137. 138. 139. 141. 143. 145. 147. 149. 148. 148. 147. 145. 143. + 141. 140. 138. 135. 133. 134. 130. 122. 115. 114. 142. 181. 210. + 217. 219. 215. 210. 214. 207. 211. 211. 208. 207. 210. 211. 209. + 208. 207. 202. 196. 193. 184. 165. 145. 97. 81. 58. 42. 37. 41. 46. + 49. 48. 50. 50. 48. 44. 40. 38. 38. 44. 57. 74. 84. 85. 89. 108. + 127. 144. 153. 163. 170. 172. 172. 173. 175. 170. 174. 176. 174. + 169. 156. 134. 114. 86. 90. 156. 197. 99. 78. 125. 109. 50. 40. 48. + 78. 75. 56. 62. 62. 72. 59. 45. 60. 44. 43. 53. 39. 81. 122. 129. + 156. 115. 90. 86. 73. 48. 84. 126. 83. 69. 127. 127. 94. 139. 140. + 144. 113. 88. 108. 137. 160. 119. 73. 40. 43. 54. 44. 40. 48. 59. + 76. 75. 67. 40. 45. 52. 67. 50. 48. 49. 52. 52. 49. 48. 50. 50. 48. + 48. 52. 59. 62. 60. 57. 60. 58. 54. 51. 56. 68. 76. 78. 75. 80. 91. + 104. 112. 114. 118. 123. 135. 139. 142. 142. 139. 138. 139. 142. + 138. 143. 149. 153. 155. 156. 157. 157. 167. 167. 169. 169. 169. + 167. 165. 163. 172. 178. 164. 125. 88. 68. 56. 46. 60. 56. 52. 51. + 50. 50. 57. 65. 55. 49. 48. 51. 53. 59. 77. 96. 92. 85. 93. 92. 75. + 80. 89. 78. 71. 70. 68. 74. 166. 156. 159. 135. 112. 113. 112. 110. + 112. 118. 122. 121. 127. 127. 128. 129. 132. 134. 136. 138. 145. + 145. 145. 145. 144. 142. 141. 140. 138. 134. 132. 131. 127. 119. + 115. 116. 154. 190. 213. 217. 217. 212. 208. 212. 206. 209. 210. + 207. 207. 209. 208. 205. 211. 203. 191. 183. 174. 152. 114. 82. 52. + 45. 37. 35. 40. 49. 56. 60. 52. 53. 53. 52. 49. 45. 42. 40. 40. 54. + 72. 80. 78. 83. 105. 129. 142. 151. 162. 170. 173. 173. 173. 174. + 165. 172. 178. 175. 166. 152. 132. 116. 125. 174. 205. 99. 88. 57. + 107. 98. 48. 43. 40. 84. 91. 63. 70. 67. 78. 58. 46. 79. 48. 47. 54. + 43. 83. 132. 121. 129. 143. 96. 66. 81. 53. 68. 97. 89. 108. 154. + 128. 76. 107. 153. 158. 105. 87. 69. 71. 164. 172. 135. 72. 16. 67. + 43. 40. 52. 56. 73. 76. 62. 42. 45. 58. 71. 50. 49. 50. 51. 51. 50. + 50. 51. 51. 50. 49. 52. 56. 59. 59. 58. 64. 60. 53. 49. 51. 61. 73. + 80. 85. 94. 108. 120. 125. 126. 127. 129. 134. 136. 139. 139. 137. + 136. 138. 139. 139. 144. 150. 155. 156. 155. 154. 154. 152. 155. + 159. 160. 162. 165. 171. 175. 186. 193. 195. 187. 176. 154. 116. 81. + 53. 46. 47. 58. 62. 56. 52. 54. 53. 49. 49. 52. 55. 63. 79. 95. 94. + 85. 93. 91. 74. 77. 89. 81. 75. 69. 74. 76. 175. 151. 154. 127. 106. + 115. 115. 107. 105. 112. 115. 112. 119. 119. 120. 121. 123. 125. + 127. 128. 135. 136. 137. 139. 140. 140. 140. 140. 139. 135. 133. + 131. 126. 119. 118. 121. 166. 197. 216. 215. 214. 210. 206. 210. + 207. 209. 210. 207. 207. 209. 206. 201. 203. 197. 188. 176. 155. + 120. 77. 45. 44. 43. 45. 50. 58. 65. 69. 70. 60. 60. 58. 57. 55. 52. + 48. 46. 38. 52. 69. 75. 73. 79. 105. 131. 138. 148. 161. 170. 173. + 173. 173. 173. 172. 179. 180. 172. 160. 151. 143. 138. 176. 193. 88. + 84. 64. 69. 111. 70. 45. 44. 39. 84. 100. 68. 66. 62. 70. 54. 52. + 91. 58. 49. 53. 45. 70. 134. 130. 107. 142. 135. 91. 49. 43. 61. 89. + 115. 144. 142. 105. 92. 89. 126. 140. 119. 121. 87. 53. 119. 159. + 173. 142. 66. 38. 41. 55. 55. 61. 77. 83. 62. 48. 49. 67. 78. 50. + 51. 51. 51. 51. 53. 53. 53. 49. 51. 53. 53. 52. 54. 58. 61. 63. 59. + 53. 48. 49. 57. 72. 83. 90. 102. 116. 124. 127. 126. 126. 125. 124. + 126. 128. 130. 131. 131. 133. 134. 138. 143. 149. 152. 152. 151. + 149. 149. 142. 145. 147. 148. 151. 158. 169. 178. 182. 187. 191. + 197. 206. 207. 188. 166. 128. 92. 58. 49. 54. 57. 58. 60. 52. 50. + 49. 52. 57. 67. 82. 95. 98. 85. 88. 88. 71. 75. 89. 84. 78. 71. 78. + 84. 179. 147. 148. 122. 113. 122. 123. 114. 108. 112. 114. 110. 113. + 113. 113. 113. 114. 115. 116. 117. 122. 123. 126. 129. 131. 133. + 134. 135. 137. 134. 132. 131. 125. 119. 120. 124. 172. 201. 216. + 213. 212. 208. 204. 208. 208. 210. 210. 208. 209. 209. 204. 197. + 193. 192. 186. 168. 136. 97. 63. 45. 35. 40. 48. 59. 69. 75. 78. 78. + 72. 69. 64. 60. 56. 52. 48. 45. 42. 54. 66. 70. 66. 73. 98. 125. + 134. 145. 159. 169. 173. 172. 171. 171. 171. 175. 173. 166. 161. + 164. 170. 172. 167. 71. 59. 72. 58. 77. 141. 34. 42. 40. 39. 72. 91. + 68. 54. 55. 60. 53. 60. 96. 79. 59. 60. 53. 65. 83. 121. 127. 114. + 126. 130. 87. 69. 81. 104. 141. 155. 115. 81. 93. 96. 88. 113. 122. + 103. 84. 81. 97. 155. 134. 138. 159. 49. 44. 49. 55. 63. 77. 85. 57. + 47. 46. 68. 75. 50. 52. 52. 50. 50. 54. 55. 54. 48. 51. 53. 52. 50. + 51. 58. 64. 58. 55. 52. 50. 50. 57. 73. 88. 90. 104. 118. 124. 125. + 126. 126. 125. 130. 132. 134. 136. 137. 139. 139. 140. 138. 141. + 145. 147. 147. 145. 144. 144. 149. 150. 150. 151. 154. 162. 174. + 183. 188. 195. 198. 196. 195. 199. 202. 202. 204. 175. 132. 89. 56. + 41. 47. 59. 50. 48. 47. 48. 55. 67. 82. 93. 101. 83. 83. 84. 70. 75. + 88. 83. 77. 73. 77. 93. 178. 147. 142. 124. 124. 129. 130. 125. 119. + 118. 118. 116. 112. 112. 110. 109. 107. 107. 107. 107. 110. 111. + 114. 117. 120. 122. 123. 124. 127. 125. 126. 125. 120. 115. 116. + 122. 174. 201. 213. 210. 209. 207. 203. 207. 209. 210. 210. 209. + 210. 209. 202. 193. 192. 184. 167. 138. 100. 64. 45. 41. 44. 50. 60. + 70. 78. 83. 84. 84. 98. 91. 81. 72. 65. 58. 52. 47. 50. 57. 64. 64. + 58. 63. 85. 110. 130. 142. 157. 168. 172. 171. 170. 169. 167. 170. + 171. 171. 174. 177. 174. 168. 101. 72. 65. 87. 79. 146. 81. 57. 43. + 36. 40. 54. 78. 73. 52. 64. 49. 50. 61. 89. 99. 72. 71. 61. 74. 36. + 82. 138. 108. 100. 117. 120. 127. 122. 139. 160. 135. 93. 79. 77. + 108. 100. 112. 124. 92. 80. 117. 134. 170. 96. 89. 159. 113. 62. 36. + 56. 57. 71. 82. 49. 44. 41. 67. 73. 48. 52. 51. 48. 48. 54. 56. 53. + 50. 50. 49. 49. 50. 54. 59. 63. 57. 55. 54. 54. 52. 56. 71. 87. 92. + 106. 119. 122. 122. 125. 128. 127. 125. 125. 127. 130. 133. 134. + 135. 134. 138. 140. 143. 143. 142. 140. 140. 141. 141. 142. 144. + 147. 153. 161. 170. 176. 179. 190. 199. 199. 196. 198. 204. 208. + 196. 207. 208. 183. 140. 95. 60. 40. 45. 43. 41. 41. 49. 63. 79. 88. + 101. 79. 79. 83. 73. 76. 85. 78. 69. 71. 72. 100. 172. 148. 138. + 129. 133. 132. 132. 134. 131. 125. 123. 125. 119. 117. 114. 111. + 108. 106. 105. 104. 102. 103. 104. 106. 108. 109. 109. 109. 112. + 112. 115. 115. 111. 106. 108. 114. 171. 197. 210. 207. 208. 206. + 203. 206. 208. 209. 209. 208. 209. 208. 199. 188. 184. 158. 123. 89. + 61. 42. 39. 45. 63. 68. 75. 81. 85. 86. 85. 85. 127. 118. 104. 91. + 81. 72. 63. 58. 57. 60. 63. 60. 52. 54. 74. 96. 128. 140. 156. 167. + 171. 170. 169. 168. 174. 177. 180. 184. 186. 176. 151. 128. 92. 78. + 53. 111. 118. 127. 78. 31. 44. 35. 41. 42. 71. 82. 59. 82. 37. 41. + 53. 74. 106. 76. 73. 60. 82. 39. 49. 117. 131. 116. 74. 69. 89. 92. + 131. 143. 87. 71. 103. 96. 88. 112. 103. 117. 118. 94. 123. 155. + 161. 114. 82. 81. 156. 81. 41. 57. 54. 68. 82. 48. 46. 45. 74. 79. + 47. 51. 50. 46. 47. 53. 55. 52. 53. 49. 45. 46. 52. 58. 61. 61. 60. + 58. 58. 58. 53. 53. 66. 83. 94. 109. 120. 120. 119. 123. 126. 126. + 124. 125. 127. 130. 134. 137. 138. 137. 138. 140. 141. 141. 139. + 138. 138. 139. 140. 142. 147. 154. 163. 171. 177. 180. 191. 193. + 194. 196. 199. 202. 201. 197. 205. 204. 203. 205. 205. 182. 127. 76. + 40. 39. 36. 35. 43. 59. 75. 84. 100. 76. 76. 83. 75. 78. 84. 73. 63. + 69. 67. 104. 167. 149. 136. 134. 137. 131. 132. 139. 139. 130. 127. + 132. 127. 124. 121. 117. 112. 109. 107. 106. 98. 99. 100. 100. 100. + 100. 99. 99. 100. 102. 105. 107. 103. 98. 100. 107. 169. 195. 207. + 205. 207. 206. 203. 206. 206. 208. 207. 206. 208. 206. 196. 185. + 165. 127. 81. 52. 42. 46. 57. 69. 63. 68. 74. 80. 82. 83. 84. 85. + 129. 128. 124. 115. 101. 86. 74. 67. 66. 67. 61. 55. 54. 52. 67. 96. + 118. 136. 156. 165. 167. 170. 172. 171. 168. 166. 186. 193. 174. + 161. 147. 119. 105. 59. 125. 116. 178. 69. 36. 45. 29. 44. 48. 38. + 42. 68. 93. 103. 28. 44. 50. 57. 116. 98. 77. 81. 91. 36. 36. 65. + 111. 142. 115. 99. 93. 75. 109. 125. 69. 94. 108. 100. 97. 110. 115. + 122. 110. 106. 125. 120. 156. 105. 75. 74. 82. 144. 61. 45. 55. 74. + 68. 49. 48. 38. 75. 68. 49. 48. 48. 49. 46. 45. 52. 62. 59. 51. 51. + 47. 50. 58. 55. 59. 61. 68. 64. 56. 54. 51. 58. 75. 94. 109. 115. + 117. 124. 123. 120. 126. 124. 128. 132. 134. 133. 133. 135. 137. + 136. 138. 141. 141. 141. 140. 141. 143. 142. 146. 152. 158. 164. + 171. 179. 184. 192. 192. 193. 195. 196. 197. 199. 199. 204. 203. + 200. 201. 208. 211. 198. 181. 104. 49. 43. 40. 42. 64. 69. 81. 106. + 67. 73. 86. 66. 70. 84. 65. 76. 64. 59. 128. 156. 157. 143. 139. + 139. 140. 140. 140. 139. 136. 134. 133. 131. 130. 128. 124. 120. + 116. 112. 110. 107. 104. 100. 97. 95. 94. 91. 89. 97. 100. 115. 114. + 108. 91. 72. 90. 157. 192. 209. 204. 204. 207. 207. 209. 201. 210. + 212. 205. 204. 204. 190. 169. 137. 83. 40. 43. 62. 69. 72. 78. 73. + 76. 81. 85. 88. 87. 86. 85. 138. 137. 134. 128. 117. 104. 91. 83. + 76. 76. 67. 58. 54. 51. 66. 96. 119. 137. 157. 165. 167. 170. 171. + 171. 173. 165. 174. 179. 166. 159. 148. 125. 102. 97. 117. 133. 157. + 59. 39. 41. 43. 44. 38. 37. 56. 85. 94. 85. 34. 25. 40. 78. 129. 90. + 76. 101. 80. 42. 42. 49. 71. 106. 115. 127. 108. 108. 118. 102. 71. + 83. 93. 113. 110. 99. 96. 124. 132. 126. 131. 118. 128. 142. 89. 42. + 99. 132. 107. 50. 51. 69. 67. 46. 43. 37. 74. 68. 53. 52. 53. 53. + 49. 47. 52. 61. 61. 54. 52. 48. 49. 55. 53. 56. 63. 70. 66. 58. 55. + 51. 59. 79. 91. 108. 114. 114. 118. 118. 119. 128. 128. 127. 127. + 129. 133. 136. 138. 138. 137. 139. 140. 140. 139. 139. 141. 143. + 144. 147. 153. 159. 165. 171. 178. 183. 189. 190. 191. 192. 194. + 195. 196. 197. 199. 202. 203. 203. 207. 212. 209. 202. 197. 126. 76. + 41. 36. 57. 65. 85. 105. 68. 72. 84. 66. 71. 85. 68. 76. 63. 64. + 135. 154. 147. 137. 141. 141. 141. 142. 141. 140. 138. 136. 135. + 136. 135. 133. 130. 126. 122. 119. 117. 112. 109. 105. 102. 100. 96. + 92. 89. 100. 105. 123. 121. 112. 91. 71. 91. 161. 194. 210. 205. + 205. 208. 208. 210. 210. 211. 209. 204. 198. 183. 154. 128. 84. 60. + 48. 60. 75. 75. 73. 75. 77. 81. 87. 89. 89. 87. 86. 86. 139. 139. + 139. 138. 135. 125. 112. 102. 90. 88. 75. 61. 53. 48. 64. 95. 121. + 139. 158. 166. 168. 170. 171. 171. 176. 166. 169. 172. 163. 156. + 145. 127. 118. 154. 119. 141. 109. 31. 35. 44. 46. 41. 33. 40. 72. + 107. 115. 104. 57. 40. 58. 98. 124. 82. 73. 100. 79. 44. 51. 70. 75. + 75. 75. 93. 120. 124. 108. 65. 73. 76. 78. 110. 129. 107. 102. 137. + 147. 131. 129. 116. 90. 129. 120. 52. 72. 104. 136. 80. 52. 64. 69. + 48. 44. 43. 79. 73. 55. 54. 54. 54. 51. 47. 50. 57. 67. 62. 56. 53. + 53. 54. 57. 57. 64. 72. 70. 62. 57. 50. 59. 82. 90. 109. 115. 112. + 115. 118. 121. 131. 129. 125. 122. 125. 133. 139. 141. 140. 140. + 140. 139. 138. 136. 137. 141. 143. 147. 150. 155. 160. 165. 171. + 178. 182. 186. 186. 187. 189. 191. 192. 194. 194. 196. 202. 206. + 204. 203. 208. 214. 217. 223. 202. 152. 78. 46. 54. 54. 64. 99. 66. + 68. 78. 64. 70. 83. 69. 72. 56. 65. 143. 154. 139. 135. 147. 144. + 144. 144. 144. 142. 141. 139. 138. 139. 138. 137. 135. 132. 129. + 126. 125. 120. 117. 114. 110. 107. 102. 96. 92. 104. 112. 132. 129. + 115. 91. 74. 98. 169. 198. 211. 206. 208. 210. 209. 212. 215. 207. + 203. 202. 187. 151. 106. 77. 40. 48. 64. 79. 84. 80. 77. 78. 83. 89. + 95. 94. 90. 85. 85. 87. 133. 133. 137. 142. 145. 139. 127. 116. 101. + 98. 81. 63. 51. 45. 62. 94. 122. 140. 159. 167. 169. 170. 172. 171. + 173. 170. 174. 176. 168. 154. 141. 130. 165. 175. 106. 113. 72. 36. + 42. 45. 37. 38. 36. 40. 62. 94. 112. 114. 112. 114. 119. 114. 100. + 74. 66. 68. 66. 41. 68. 110. 98. 60. 62. 97. 106. 98. 82. 42. 74. + 79. 78. 93. 123. 119. 124. 150. 145. 126. 135. 132. 74. 58. 132. + 115. 37. 71. 120. 129. 54. 54. 66. 48. 44. 48. 80. 73. 53. 51. 52. + 53. 51. 47. 49. 54. 65. 65. 54. 54. 53. 51. 60. 59. 64. 74. 75. 69. + 59. 48. 57. 83. 91. 110. 116. 114. 120. 124. 124. 129. 124. 124. + 125. 129. 134. 139. 141. 142. 142. 141. 139. 136. 135. 137. 141. + 145. 150. 153. 157. 161. 165. 170. 176. 180. 183. 184. 185. 187. + 189. 191. 192. 193. 196. 201. 204. 202. 199. 201. 208. 214. 199. + 220. 208. 156. 100. 52. 36. 61. 89. 62. 62. 69. 61. 69. 80. 69. 67. + 46. 62. 150. 156. 137. 138. 154. 147. 147. 147. 146. 144. 143. 142. + 141. 139. 138. 137. 136. 134. 132. 129. 128. 125. 123. 120. 118. + 115. 110. 103. 99. 109. 116. 135. 131. 115. 92. 82. 115. 179. 203. + 212. 208. 210. 212. 210. 213. 212. 201. 199. 199. 173. 118. 69. 47. + 43. 62. 82. 87. 83. 81. 83. 85. 89. 96. 100. 97. 89. 84. 85. 88. + 131. 132. 138. 146. 151. 147. 135. 125. 111. 107. 87. 66. 50. 42. + 60. 93. 122. 140. 159. 168. 169. 171. 173. 173. 171. 175. 179. 178. + 170. 153. 145. 149. 211. 153. 92. 83. 65. 70. 57. 42. 40. 42. 40. + 39. 47. 62. 70. 69. 89. 108. 107. 86. 64. 65. 65. 64. 82. 82. 102. + 109. 65. 33. 78. 140. 75. 55. 70. 54. 72. 80. 91. 88. 95. 110. 125. + 143. 136. 133. 153. 151. 96. 19. 93. 156. 89. 55. 97. 153. 66. 42. + 55. 43. 41. 47. 74. 67. 53. 50. 51. 53. 53. 50. 52. 56. 59. 64. 48. + 52. 52. 47. 64. 60. 63. 76. 82. 78. 64. 46. 53. 80. 90. 110. 116. + 115. 124. 129. 124. 122. 118. 125. 133. 136. 136. 136. 139. 143. + 143. 142. 139. 136. 135. 137. 143. 147. 153. 155. 159. 162. 165. + 169. 174. 177. 181. 182. 183. 185. 187. 189. 191. 192. 196. 197. + 199. 201. 202. 202. 204. 207. 211. 211. 210. 215. 174. 83. 43. 68. + 80. 60. 58. 64. 62. 70. 78. 70. 68. 41. 63. 155. 157. 137. 140. 152. + 149. 149. 148. 146. 145. 144. 143. 143. 139. 139. 139. 138. 136. + 134. 132. 131. 127. 126. 125. 124. 122. 118. 113. 109. 113. 117. + 134. 130. 114. 96. 97. 140. 188. 207. 213. 209. 212. 213. 210. 214. + 209. 200. 198. 192. 152. 90. 50. 41. 66. 82. 93. 89. 82. 83. 87. 90. + 96. 101. 103. 97. 88. 83. 86. 91. 130. 133. 141. 149. 154. 151. 142. + 134. 124. 118. 97. 72. 53. 42. 59. 93. 121. 140. 159. 168. 171. 173. + 175. 175. 172. 178. 177. 172. 167. 152. 152. 171. 219. 133. 119. + 100. 52. 62. 49. 44. 54. 51. 48. 51. 61. 63. 50. 33. 54. 69. 60. 58. + 52. 60. 58. 74. 83. 96. 91. 68. 31. 37. 101. 142. 59. 37. 72. 79. + 67. 76. 97. 99. 88. 99. 107. 127. 134. 140. 154. 140. 128. 57. 47. + 141. 180. 72. 94. 129. 102. 45. 50. 43. 44. 50. 71. 68. 57. 53. 52. + 55. 55. 54. 56. 60. 61. 70. 50. 58. 58. 50. 74. 68. 62. 79. 91. 90. + 71. 46. 49. 77. 86. 109. 117. 114. 122. 126. 120. 116. 119. 129. + 140. 142. 137. 134. 138. 143. 142. 142. 140. 138. 137. 140. 145. + 149. 155. 157. 160. 162. 164. 167. 171. 174. 178. 179. 181. 183. + 185. 188. 189. 190. 194. 192. 195. 202. 206. 206. 206. 208. 215. + 217. 206. 218. 217. 165. 98. 41. 72. 59. 56. 60. 64. 73. 77. 71. 70. + 44. 70. 161. 154. 135. 140. 146. 150. 149. 147. 145. 144. 144. 143. + 143. 143. 143. 142. 141. 140. 138. 136. 135. 130. 128. 127. 127. + 126. 124. 120. 117. 118. 118. 132. 129. 116. 104. 113. 163. 197. + 211. 213. 209. 213. 213. 210. 214. 208. 200. 195. 178. 129. 71. 46. + 52. 80. 89. 95. 92. 87. 87. 90. 93. 104. 104. 102. 96. 88. 86. 90. + 95. 115. 122. 134. 144. 151. 151. 148. 145. 138. 133. 110. 82. 58. + 45. 60. 93. 120. 139. 159. 168. 171. 175. 177. 177. 174. 180. 174. + 170. 169. 153. 150. 172. 203. 116. 132. 131. 33. 37. 40. 48. 56. 53. + 52. 60. 73. 76. 61. 43. 76. 86. 58. 63. 72. 75. 48. 60. 45. 50. 44. + 52. 47. 57. 105. 120. 76. 47. 63. 81. 64. 74. 84. 102. 100. 95. 96. + 125. 138. 135. 138. 118. 135. 111. 59. 116. 177. 112. 95. 82. 151. + 59. 49. 45. 48. 54. 72. 73. 62. 56. 53. 54. 54. 53. 55. 59. 64. 76. + 53. 62. 61. 51. 79. 72. 62. 83. 101. 102. 80. 48. 46. 74. 84. 113. + 123. 115. 116. 120. 119. 121. 127. 134. 140. 141. 138. 136. 138. + 142. 141. 141. 141. 140. 140. 143. 148. 151. 156. 158. 160. 161. + 162. 164. 168. 171. 175. 176. 177. 180. 182. 185. 187. 187. 192. + 190. 194. 201. 205. 204. 207. 212. 202. 222. 211. 210. 222. 221. + 168. 64. 61. 54. 51. 55. 63. 71. 73. 67. 65. 47. 81. 166. 150. 133. + 143. 147. 149. 148. 146. 144. 143. 142. 143. 143. 145. 144. 144. + 143. 141. 139. 137. 136. 133. 131. 129. 128. 127. 126. 123. 121. + 123. 120. 133. 131. 123. 114. 126. 179. 203. 213. 212. 209. 214. + 213. 209. 213. 206. 197. 184. 157. 108. 63. 54. 70. 87. 90. 93. 94. + 91. 90. 95. 102. 111. 108. 101. 94. 90. 91. 96. 100. 96. 106. 121. + 136. 145. 150. 152. 153. 149. 143. 120. 89. 63. 47. 61. 94. 119. + 138. 158. 168. 172. 176. 178. 179. 174. 181. 174. 173. 175. 154. + 140. 157. 194. 92. 97. 134. 27. 44. 49. 44. 46. 47. 48. 53. 60. 66. + 64. 59. 45. 67. 35. 45. 77. 97. 57. 56. 49. 42. 45. 79. 63. 29. 60. + 83. 103. 63. 44. 66. 63. 77. 66. 92. 104. 91. 94. 133. 144. 128. + 128. 115. 123. 132. 104. 114. 103. 144. 89. 49. 181. 66. 46. 42. 46. + 51. 68. 73. 64. 57. 52. 51. 51. 50. 52. 55. 59. 73. 47. 58. 56. 44. + 74. 66. 63. 86. 107. 110. 86. 50. 45. 72. 84. 119. 131. 118. 112. + 115. 120. 129. 136. 137. 138. 139. 138. 139. 139. 140. 140. 141. + 142. 142. 142. 145. 149. 153. 156. 158. 160. 161. 161. 163. 166. + 169. 172. 173. 175. 177. 180. 182. 184. 185. 192. 191. 194. 200. + 200. 198. 203. 212. 211. 210. 203. 221. 220. 213. 208. 156. 52. 48. + 45. 49. 59. 67. 67. 62. 56. 46. 87. 170. 147. 132. 148. 152. 149. + 147. 145. 143. 142. 141. 142. 142. 144. 144. 143. 142. 140. 137. + 135. 134. 136. 133. 130. 128. 127. 126. 124. 122. 127. 122. 135. + 135. 128. 120. 133. 186. 206. 214. 212. 209. 214. 213. 209. 213. + 202. 191. 172. 141. 96. 62. 64. 84. 94. 92. 92. 94. 91. 90. 100. + 114. 116. 110. 101. 94. 91. 94. 100. 105. 60. 83. 111. 130. 142. + 152. 159. 162. 158. 145. 127. 102. 64. 40. 58. 93. 122. 145. 160. + 167. 177. 177. 173. 176. 177. 177. 179. 177. 167. 155. 154. 161. + 147. 115. 66. 77. 32. 31. 52. 41. 46. 37. 48. 64. 63. 57. 56. 52. + 51. 42. 38. 50. 101. 98. 53. 78. 54. 41. 40. 74. 83. 40. 31. 74. 99. + 94. 61. 48. 77. 71. 61. 83. 96. 108. 88. 129. 145. 128. 114. 143. + 135. 136. 109. 125. 63. 133. 163. 43. 160. 125. 37. 30. 45. 43. 80. + 61. 50. 67. 45. 54. 48. 52. 49. 50. 61. 69. 53. 50. 49. 41. 59. 75. + 59. 94. 114. 115. 99. 61. 43. 62. 85. 112. 115. 104. 114. 132. 135. + 131. 133. 134. 137. 139. 140. 139. 138. 136. 140. 139. 138. 139. + 140. 143. 146. 148. 152. 155. 158. 160. 161. 163. 165. 167. 169. + 171. 174. 176. 178. 180. 183. 186. 190. 191. 193. 196. 198. 201. + 203. 204. 207. 209. 213. 216. 217. 216. 214. 213. 123. 50. 42. 55. + 50. 75. 47. 67. 49. 45. 103. 161. 140. 131. 158. 141. 145. 144. 144. + 144. 144. 144. 143. 143. 144. 144. 143. 143. 141. 140. 138. 137. + 131. 137. 136. 129. 124. 126. 126. 123. 129. 133. 140. 138. 126. + 127. 158. 195. 210. 213. 213. 211. 212. 214. 213. 209. 201. 186. + 153. 108. 76. 71. 83. 95. 92. 92. 91. 92. 95. 101. 107. 111. 110. + 103. 95. 92. 93. 97. 100. 101. 48. 69. 96. 119. 137. 153. 161. 163. + 164. 152. 136. 111. 71. 44. 59. 93. 122. 145. 159. 167. 177. 177. + 173. 176. 177. 176. 178. 177. 168. 156. 152. 155. 179. 109. 80. 48. + 44. 46. 43. 41. 48. 41. 56. 73. 63. 50. 53. 60. 48. 48. 43. 56. 108. + 97. 48. 77. 56. 32. 38. 77. 99. 65. 37. 67. 89. 84. 78. 68. 67. 80. + 85. 71. 77. 103. 93. 114. 111. 111. 119. 143. 134. 170. 133. 112. + 34. 79. 152. 92. 146. 146. 42. 33. 42. 37. 73. 60. 53. 69. 45. 53. + 47. 52. 50. 51. 65. 72. 54. 52. 52. 42. 57. 69. 64. 97. 116. 117. + 103. 63. 42. 59. 80. 108. 115. 108. 119. 134. 134. 130. 133. 134. + 136. 138. 139. 139. 139. 138. 141. 140. 139. 140. 141. 144. 147. + 149. 151. 154. 158. 160. 161. 162. 164. 166. 168. 171. 174. 176. + 177. 179. 183. 185. 190. 191. 193. 195. 198. 201. 203. 204. 205. + 207. 210. 214. 216. 217. 217. 217. 171. 103. 36. 48. 46. 66. 46. 65. + 49. 46. 112. 160. 137. 134. 152. 143. 147. 147. 147. 146. 146. 146. + 145. 145. 143. 143. 142. 142. 141. 140. 138. 138. 132. 136. 135. + 130. 127. 129. 128. 123. 128. 132. 139. 139. 131. 134. 164. 198. + 214. 216. 216. 213. 213. 215. 213. 209. 200. 176. 136. 97. 76. 76. + 86. 95. 90. 90. 92. 96. 102. 107. 111. 113. 102. 98. 94. 93. 96. + 100. 102. 103. 35. 51. 76. 102. 130. 153. 165. 166. 168. 158. 144. + 119. 76. 45. 56. 87. 122. 144. 159. 167. 177. 177. 173. 177. 178. + 176. 177. 176. 170. 158. 150. 147. 159. 132. 96. 62. 49. 40. 35. 43. + 47. 46. 65. 78. 59. 41. 48. 63. 45. 54. 45. 63. 118. 95. 42. 74. 62. + 36. 41. 55. 84. 84. 45. 48. 86. 64. 83. 96. 67. 86. 105. 77. 60. 92. + 96. 112. 97. 111. 123. 117. 134. 184. 152. 112. 40. 29. 103. 120. + 131. 176. 47. 37. 39. 33. 68. 63. 56. 72. 46. 52. 45. 51. 50. 53. + 68. 73. 54. 54. 55. 44. 54. 60. 72. 102. 118. 118. 105. 66. 42. 56. + 76. 104. 116. 114. 126. 136. 133. 129. 133. 134. 135. 136. 138. 139. + 140. 140. 141. 141. 140. 141. 143. 145. 148. 149. 151. 153. 157. + 159. 160. 161. 163. 165. 168. 170. 173. 176. 177. 179. 182. 185. + 189. 190. 192. 195. 198. 200. 203. 204. 203. 205. 208. 211. 215. + 218. 220. 221. 215. 165. 48. 40. 46. 60. 44. 59. 47. 46. 126. 158. + 133. 138. 144. 148. 147. 147. 147. 146. 146. 145. 145. 145. 142. + 142. 141. 141. 140. 139. 139. 138. 135. 136. 134. 131. 130. 131. + 128. 123. 125. 130. 140. 145. 144. 150. 175. 203. 215. 217. 215. + 212. 213. 215. 212. 207. 198. 161. 114. 84. 78. 84. 91. 93. 92. 92. + 95. 102. 109. 112. 110. 108. 93. 92. 93. 95. 100. 103. 104. 104. 29. + 40. 59. 88. 124. 155. 168. 168. 169. 161. 149. 123. 77. 41. 49. 78. + 121. 144. 159. 167. 177. 178. 174. 177. 178. 177. 176. 176. 172. + 161. 148. 139. 119. 170. 80. 80. 36. 34. 45. 44. 44. 52. 69. 71. 50. + 40. 48. 54. 44. 56. 41. 68. 127. 94. 39. 68. 68. 49. 45. 25. 51. 91. + 66. 56. 93. 52. 67. 107. 79. 86. 104. 103. 81. 87. 84. 106. 94. 123. + 134. 105. 140. 161. 140. 96. 63. 27. 58. 139. 132. 200. 49. 38. 38. + 35. 70. 66. 61. 75. 47. 52. 45. 51. 51. 54. 67. 70. 51. 52. 57. 47. + 53. 56. 82. 106. 115. 115. 104. 68. 43. 54. 79. 104. 116. 118. 129. + 135. 131. 128. 134. 134. 134. 135. 137. 139. 141. 142. 141. 141. + 141. 142. 144. 146. 148. 149. 149. 152. 156. 158. 159. 160. 162. + 164. 167. 170. 173. 175. 176. 178. 181. 184. 187. 189. 191. 194. + 197. 200. 202. 203. 205. 205. 207. 209. 213. 217. 220. 223. 227. + 199. 97. 38. 47. 57. 39. 51. 41. 48. 138. 156. 130. 144. 141. 155. + 146. 145. 145. 144. 144. 143. 142. 142. 141. 141. 140. 139. 139. + 138. 139. 139. 137. 135. 133. 130. 130. 129. 125. 121. 123. 131. + 145. 157. 162. 170. 188. 207. 214. 215. 213. 211. 212. 214. 210. + 203. 189. 144. 96. 78. 85. 93. 93. 90. 97. 97. 101. 108. 112. 111. + 104. 97. 87. 89. 94. 99. 102. 104. 104. 103. 31. 36. 51. 79. 119. + 154. 170. 170. 170. 163. 151. 124. 76. 37. 44. 73. 120. 143. 159. + 167. 177. 178. 174. 178. 178. 178. 177. 176. 172. 163. 147. 135. + 110. 164. 74. 53. 31. 48. 54. 42. 46. 58. 69. 59. 43. 48. 54. 44. + 46. 52. 36. 74. 132. 93. 41. 60. 76. 51. 43. 26. 40. 77. 81. 85. 94. + 66. 54. 89. 79. 90. 95. 116. 115. 90. 68. 90. 80. 119. 150. 133. + 145. 141. 127. 57. 56. 56. 52. 167. 155. 206. 48. 38. 38. 38. 73. + 62. 64. 78. 49. 53. 45. 51. 51. 54. 62. 65. 46. 49. 56. 48. 55. 59. + 91. 108. 111. 109. 103. 69. 45. 54. 86. 106. 116. 120. 129. 132. + 128. 130. 135. 135. 135. 135. 137. 139. 140. 141. 140. 141. 142. + 143. 144. 146. 148. 149. 148. 151. 155. 157. 158. 159. 161. 163. + 166. 169. 172. 174. 175. 177. 180. 183. 186. 187. 190. 193. 196. + 199. 202. 203. 207. 207. 207. 208. 211. 215. 218. 220. 222. 210. + 162. 48. 40. 51. 34. 47. 34. 55. 144. 154. 131. 147. 143. 158. 146. + 146. 145. 144. 143. 143. 142. 141. 142. 141. 139. 138. 137. 137. + 138. 138. 138. 134. 131. 129. 127. 124. 121. 120. 127. 140. 159. + 174. 182. 188. 200. 211. 214. 214. 213. 212. 214. 215. 208. 199. + 174. 128. 87. 81. 94. 98. 92. 88. 98. 100. 105. 110. 112. 108. 98. + 91. 87. 91. 97. 101. 103. 103. 102. 101. 35. 37. 47. 73. 113. 151. + 168. 170. 173. 165. 154. 125. 75. 36. 43. 73. 120. 143. 158. 167. + 177. 178. 175. 178. 177. 180. 180. 177. 172. 163. 149. 135. 104. + 120. 121. 38. 49. 55. 39. 42. 54. 60. 64. 52. 43. 54. 58. 43. 47. + 47. 38. 90. 134. 87. 43. 49. 87. 50. 36. 51. 49. 44. 63. 82. 77. 83. + 55. 66. 66. 99. 92. 107. 110. 88. 70. 91. 76. 108. 150. 154. 134. + 151. 144. 54. 42. 73. 54. 157. 181. 187. 46. 39. 37. 38. 77. 56. 67. + 80. 52. 55. 46. 51. 50. 53. 60. 63. 43. 46. 54. 49. 60. 67. 95. 108. + 107. 107. 105. 74. 47. 54. 91. 107. 116. 122. 131. 129. 126. 131. + 135. 135. 136. 137. 138. 138. 139. 139. 139. 140. 141. 143. 144. + 146. 147. 148. 147. 150. 153. 156. 156. 158. 160. 162. 165. 168. + 171. 173. 174. 177. 180. 182. 185. 186. 189. 192. 196. 199. 202. + 203. 208. 208. 208. 209. 211. 213. 216. 218. 222. 216. 208. 86. 33. + 41. 31. 45. 30. 66. 145. 154. 134. 146. 147. 156. 149. 149. 148. + 147. 146. 144. 144. 143. 143. 141. 139. 137. 135. 135. 136. 136. + 136. 132. 130. 128. 124. 120. 122. 127. 143. 158. 177. 191. 196. + 200. 207. 213. 216. 216. 216. 215. 216. 214. 203. 191. 153. 114. 85. + 88. 99. 97. 92. 93. 97. 102. 108. 111. 110. 104. 96. 91. 91. 95. 99. + 102. 102. 101. 101. 101. 37. 37. 44. 67. 107. 146. 165. 169. 174. + 166. 153. 123. 72. 34. 43. 75. 119. 143. 158. 167. 177. 178. 175. + 179. 176. 181. 182. 177. 171. 163. 150. 138. 122. 103. 138. 45. 59. + 47. 28. 50. 62. 53. 52. 51. 45. 49. 54. 49. 46. 45. 50. 112. 135. + 78. 44. 38. 83. 56. 33. 65. 57. 32. 57. 53. 54. 70. 52. 69. 59. 99. + 92. 100. 97. 92. 77. 95. 79. 105. 140. 146. 122. 160. 148. 90. 48. + 59. 47. 132. 189. 146. 39. 41. 36. 38. 85. 56. 68. 82. 54. 57. 48. + 52. 50. 52. 62. 65. 44. 45. 52. 49. 65. 75. 95. 107. 107. 109. 111. + 81. 51. 53. 90. 105. 115. 125. 134. 130. 126. 133. 135. 136. 138. + 138. 139. 138. 137. 136. 138. 139. 140. 142. 144. 145. 146. 146. + 146. 149. 153. 155. 156. 157. 159. 161. 165. 167. 171. 173. 174. + 176. 179. 182. 184. 185. 188. 191. 195. 199. 201. 203. 207. 207. + 208. 209. 211. 214. 216. 217. 222. 221. 218. 151. 40. 38. 35. 39. + 29. 81. 144. 156. 137. 141. 151. 149. 149. 149. 148. 147. 145. 144. + 143. 143. 144. 142. 139. 136. 134. 134. 134. 134. 132. 130. 129. + 128. 122. 119. 126. 138. 166. 181. 196. 203. 202. 204. 209. 215. + 216. 217. 216. 215. 214. 208. 193. 177. 131. 101. 84. 92. 98. 91. + 92. 102. 101. 107. 113. 113. 106. 98. 93. 92. 94. 97. 101. 102. 101. + 101. 103. 104. 36. 36. 41. 63. 102. 141. 163. 168. 172. 164. 150. + 119. 68. 31. 41. 75. 119. 142. 158. 167. 177. 179. 175. 179. 176. + 182. 184. 178. 170. 163. 152. 140. 173. 124. 91. 41. 51. 44. 42. 58. + 65. 43. 41. 52. 46. 39. 46. 56. 44. 44. 62. 129. 135. 71. 43. 32. + 66. 64. 34. 61. 59. 49. 81. 42. 38. 42. 44. 86. 62. 92. 92. 104. + 109. 104. 74. 79. 70. 105. 137. 140. 122. 154. 121. 114. 56. 38. 49. + 137. 184. 111. 32. 41. 36. 39. 94. 61. 68. 82. 55. 58. 49. 52. 49. + 51. 65. 68. 46. 46. 51. 49. 68. 81. 94. 106. 108. 113. 117. 86. 53. + 52. 87. 102. 114. 127. 138. 132. 126. 134. 135. 137. 139. 140. 139. + 138. 135. 134. 137. 138. 140. 142. 143. 145. 145. 145. 146. 149. + 152. 154. 155. 156. 159. 160. 164. 167. 170. 172. 174. 176. 179. + 181. 183. 185. 187. 191. 195. 198. 201. 203. 204. 205. 207. 210. + 212. 215. 216. 217. 218. 223. 210. 206. 55. 41. 39. 32. 30. 91. 143. + 157. 139. 137. 153. 144. 147. 147. 146. 145. 143. 142. 141. 140. + 145. 143. 139. 136. 133. 132. 133. 133. 129. 128. 128. 128. 122. + 120. 131. 147. 184. 197. 208. 208. 203. 203. 209. 215. 215. 215. + 214. 212. 209. 201. 182. 164. 117. 93. 83. 93. 96. 87. 93. 111. 108. + 115. 119. 115. 104. 93. 89. 89. 95. 98. 101. 101. 100. 101. 104. + 108. 33. 34. 38. 56. 96. 139. 161. 163. 172. 167. 151. 123. 79. 35. + 37. 75. 115. 143. 161. 167. 176. 179. 177. 178. 176. 180. 181. 177. + 171. 162. 147. 134. 165. 117. 71. 47. 54. 31. 57. 62. 51. 46. 45. + 41. 40. 51. 53. 39. 44. 41. 99. 121. 139. 61. 47. 41. 45. 59. 43. + 72. 58. 48. 54. 55. 49. 48. 45. 54. 72. 78. 85. 101. 118. 107. 59. + 78. 59. 96. 150. 135. 135. 141. 128. 144. 111. 71. 65. 149. 156. 81. + 138. 25. 38. 59. 92. 63. 72. 66. 57. 51. 48. 50. 52. 53. 54. 55. 56. + 55. 51. 53. 68. 84. 103. 117. 120. 122. 120. 84. 52. 56. 89. 105. + 121. 128. 131. 134. 135. 134. 136. 136. 137. 138. 138. 138. 137. + 137. 135. 136. 138. 140. 142. 144. 146. 147. 147. 148. 150. 152. + 154. 157. 158. 159. 161. 163. 165. 168. 172. 175. 178. 179. 182. + 184. 188. 191. 193. 196. 200. 203. 205. 207. 209. 210. 210. 211. + 213. 215. 216. 220. 224. 217. 130. 36. 30. 32. 29. 108. 133. 151. + 144. 148. 144. 150. 147. 147. 146. 146. 145. 144. 143. 143. 140. + 139. 137. 135. 133. 132. 132. 132. 125. 126. 128. 132. 129. 118. + 136. 176. 202. 210. 215. 210. 205. 206. 210. 213. 213. 216. 217. + 215. 211. 197. 169. 143. 99. 95. 91. 88. 90. 95. 101. 106. 114. 116. + 115. 109. 99. 91. 89. 91. 99. 104. 105. 101. 101. 105. 104. 99. 34. + 33. 35. 51. 91. 136. 161. 165. 174. 169. 153. 125. 80. 35. 35. 72. + 115. 143. 161. 167. 176. 179. 176. 178. 175. 180. 181. 177. 171. + 162. 148. 135. 148. 94. 46. 38. 63. 48. 60. 50. 49. 39. 42. 49. 46. + 44. 43. 34. 25. 69. 134. 129. 115. 62. 51. 39. 45. 57. 50. 69. 55. + 52. 45. 44. 50. 57. 52. 52. 64. 69. 73. 88. 121. 106. 55. 60. 63. + 115. 150. 128. 139. 152. 97. 91. 139. 100. 117. 180. 144. 139. 173. + 57. 40. 38. 76. 55. 66. 65. 63. 61. 58. 53. 48. 44. 50. 51. 53. 55. + 56. 63. 82. 100. 114. 122. 121. 125. 120. 82. 55. 67. 90. 105. 121. + 128. 130. 133. 134. 133. 136. 137. 137. 138. 138. 138. 137. 136. + 136. 137. 138. 140. 142. 143. 145. 146. 147. 147. 149. 152. 154. + 156. 158. 159. 161. 162. 165. 168. 171. 174. 177. 178. 181. 184. + 188. 191. 193. 196. 199. 202. 204. 206. 209. 210. 210. 211. 213. + 215. 218. 227. 224. 216. 164. 41. 32. 29. 36. 115. 136. 148. 141. + 149. 147. 148. 147. 147. 146. 145. 144. 144. 143. 143. 140. 139. + 137. 135. 134. 133. 132. 131. 129. 128. 125. 127. 125. 119. 141. + 184. 205. 213. 217. 211. 206. 208. 212. 214. 219. 219. 216. 212. + 206. 188. 155. 125. 99. 96. 91. 89. 90. 95. 101. 106. 112. 113. 112. + 105. 97. 91. 91. 94. 101. 105. 105. 101. 100. 102. 100. 95. 33. 32. + 32. 47. 86. 132. 161. 167. 176. 171. 155. 128. 83. 36. 34. 69. 114. + 143. 161. 167. 176. 179. 176. 177. 177. 181. 182. 178. 173. 164. + 150. 138. 138. 90. 45. 45. 68. 53. 55. 39. 52. 36. 38. 50. 46. 40. + 40. 39. 76. 98. 114. 103. 87. 68. 50. 31. 45. 55. 62. 66. 49. 56. + 34. 36. 47. 64. 57. 46. 57. 64. 63. 73. 124. 115. 78. 66. 79. 131. + 146. 134. 148. 167. 132. 98. 138. 81. 137. 161. 115. 121. 114. 47. + 46. 44. 75. 58. 60. 58. 55. 53. 54. 57. 62. 65. 48. 49. 52. 56. 61. + 73. 95. 115. 124. 124. 120. 125. 118. 75. 54. 78. 91. 106. 121. 127. + 130. 132. 133. 133. 137. 137. 138. 138. 138. 138. 137. 136. 137. + 137. 138. 139. 141. 142. 143. 144. 146. 147. 149. 151. 153. 156. + 157. 158. 161. 162. 164. 167. 170. 173. 176. 177. 181. 184. 187. + 190. 192. 195. 199. 202. 204. 206. 208. 209. 209. 210. 212. 215. + 215. 228. 221. 216. 204. 64. 31. 30. 43. 124. 141. 145. 138. 152. + 149. 145. 146. 146. 145. 145. 144. 143. 142. 142. 140. 139. 138. + 136. 134. 133. 132. 131. 132. 129. 123. 121. 121. 120. 149. 194. + 210. 216. 218. 212. 207. 209. 214. 216. 221. 218. 213. 208. 199. + 177. 140. 109. 101. 97. 93. 90. 91. 96. 102. 106. 112. 111. 108. + 101. 94. 91. 94. 97. 103. 105. 105. 101. 99. 97. 93. 88. 31. 30. 31. + 46. 84. 131. 160. 168. 175. 171. 156. 131. 88. 40. 36. 69. 113. 142. + 161. 167. 177. 179. 175. 176. 177. 181. 182. 178. 173. 165. 152. + 140. 125. 97. 61. 59. 61. 44. 48. 43. 54. 41. 40. 43. 41. 45. 53. + 53. 113. 85. 62. 85. 82. 71. 41. 38. 44. 55. 72. 63. 41. 57. 30. 39. + 43. 67. 54. 39. 59. 70. 61. 63. 108. 114. 110. 96. 104. 129. 133. + 146. 142. 105. 126. 130. 163. 146. 195. 145. 62. 38. 39. 53. 68. 66. + 57. 40. 71. 67. 60. 53. 49. 49. 53. 56. 50. 50. 52. 57. 64. 78. 100. + 120. 126. 122. 117. 125. 114. 66. 49. 83. 94. 108. 122. 128. 129. + 132. 133. 132. 138. 138. 139. 139. 138. 138. 137. 136. 137. 137. + 138. 139. 140. 141. 142. 142. 145. 146. 148. 150. 153. 155. 157. + 158. 160. 161. 163. 166. 169. 172. 174. 175. 180. 183. 186. 189. + 191. 194. 198. 201. 203. 205. 207. 208. 208. 209. 212. 214. 211. + 220. 217. 217. 226. 111. 23. 35. 45. 128. 143. 144. 138. 156. 151. + 141. 145. 145. 145. 144. 143. 142. 142. 141. 139. 139. 138. 137. + 135. 134. 132. 131. 131. 129. 122. 120. 120. 125. 156. 201. 212. + 217. 217. 211. 207. 210. 214. 216. 216. 215. 212. 205. 189. 163. + 132. 109. 104. 100. 96. 93. 94. 98. 104. 109. 115. 112. 105. 97. 92. + 91. 96. 100. 104. 105. 104. 101. 97. 92. 87. 83. 29. 30. 33. 48. 85. + 130. 158. 166. 173. 169. 156. 134. 93. 45. 39. 69. 112. 141. 160. + 167. 177. 179. 174. 175. 173. 177. 178. 174. 169. 163. 150. 139. + 117. 98. 63. 61. 52. 40. 47. 50. 46. 47. 49. 42. 41. 60. 71. 60. 67. + 51. 50. 102. 92. 71. 39. 54. 45. 57. 74. 62. 37. 55. 34. 49. 44. 69. + 51. 37. 70. 80. 59. 55. 72. 81. 108. 120. 130. 124. 123. 147. 133. + 71. 111. 121. 132. 151. 164. 127. 96. 50. 65. 78. 59. 71. 54. 57. + 52. 57. 63. 66. 63. 57. 53. 51. 49. 48. 52. 59. 68. 82. 103. 121. + 125. 121. 118. 126. 112. 61. 47. 86. 98. 111. 124. 129. 129. 131. + 133. 132. 139. 139. 139. 139. 139. 138. 137. 136. 136. 136. 137. + 138. 139. 140. 141. 141. 144. 145. 147. 149. 152. 154. 156. 157. + 159. 160. 162. 165. 168. 170. 172. 173. 179. 182. 186. 189. 191. + 194. 197. 200. 202. 204. 207. 208. 208. 209. 211. 213. 213. 212. + 216. 219. 223. 161. 20. 35. 47. 128. 142. 143. 140. 158. 152. 139. + 145. 144. 144. 143. 142. 141. 141. 141. 139. 139. 139. 138. 137. + 134. 132. 131. 127. 129. 124. 122. 124. 130. 161. 204. 212. 215. + 214. 207. 205. 209. 214. 216. 212. 215. 214. 201. 176. 147. 126. + 116. 107. 104. 99. 96. 96. 101. 107. 111. 117. 112. 104. 95. 91. 92. + 97. 102. 105. 103. 102. 100. 95. 89. 84. 82. 29. 31. 34. 48. 83. + 127. 156. 164. 172. 168. 158. 137. 98. 49. 40. 69. 111. 141. 160. + 167. 177. 179. 174. 174. 169. 173. 173. 170. 165. 159. 148. 137. + 136. 110. 61. 60. 50. 47. 47. 44. 36. 48. 57. 49. 48. 68. 74. 55. + 41. 44. 55. 99. 90. 75. 47. 52. 49. 59. 63. 62. 41. 52. 42. 53. 48. + 72. 50. 41. 81. 87. 55. 49. 46. 48. 84. 125. 149. 127. 131. 138. + 114. 86. 104. 82. 91. 131. 131. 162. 178. 146. 140. 114. 76. 89. 60. + 61. 62. 65. 67. 66. 61. 58. 59. 61. 45. 46. 52. 63. 75. 89. 108. + 125. 124. 125. 124. 128. 112. 63. 51. 91. 102. 115. 127. 130. 130. + 132. 134. 133. 140. 140. 140. 140. 139. 138. 137. 136. 134. 135. + 136. 137. 139. 140. 141. 141. 144. 145. 146. 149. 151. 153. 155. + 156. 159. 160. 162. 164. 167. 169. 171. 172. 178. 181. 185. 188. + 190. 193. 196. 199. 201. 204. 206. 207. 207. 208. 210. 212. 218. + 212. 215. 222. 215. 194. 44. 29. 56. 129. 139. 143. 141. 157. 151. + 141. 144. 144. 143. 142. 141. 141. 140. 140. 139. 139. 140. 139. + 137. 135. 132. 131. 124. 129. 126. 124. 127. 135. 165. 206. 211. + 213. 210. 204. 203. 209. 215. 216. 215. 216. 211. 193. 160. 131. + 118. 119. 109. 106. 101. 97. 98. 102. 108. 112. 115. 109. 100. 92. + 90. 93. 99. 103. 104. 100. 98. 98. 94. 88. 85. 86. 30. 31. 32. 43. + 77. 122. 154. 164. 173. 170. 160. 140. 101. 51. 39. 66. 110. 140. + 160. 168. 177. 179. 173. 174. 171. 174. 174. 171. 167. 161. 150. + 140. 146. 119. 62. 61. 47. 49. 46. 43. 40. 46. 55. 52. 48. 60. 64. + 49. 59. 51. 51. 78. 81. 73. 50. 45. 56. 61. 46. 62. 51. 51. 47. 47. + 45. 72. 52. 47. 90. 87. 50. 50. 42. 43. 74. 121. 143. 117. 141. 122. + 135. 104. 78. 30. 36. 69. 58. 51. 58. 88. 84. 101. 134. 142. 117. + 129. 115. 106. 89. 68. 50. 42. 45. 50. 46. 48. 58. 71. 84. 97. 113. + 126. 123. 129. 127. 126. 108. 64. 57. 97. 105. 118. 129. 132. 131. + 133. 135. 134. 140. 140. 140. 140. 139. 138. 137. 136. 132. 133. + 135. 136. 138. 140. 141. 142. 143. 144. 146. 148. 150. 153. 155. + 155. 158. 159. 161. 163. 166. 168. 169. 170. 178. 181. 184. 187. + 189. 192. 196. 199. 201. 203. 205. 206. 206. 207. 210. 212. 217. + 217. 211. 221. 216. 205. 97. 26. 71. 134. 137. 143. 141. 153. 149. + 146. 143. 143. 142. 142. 141. 140. 139. 139. 139. 140. 140. 140. + 138. 135. 132. 131. 123. 130. 128. 125. 128. 138. 168. 208. 211. + 212. 208. 203. 203. 210. 217. 218. 217. 212. 201. 178. 146. 120. + 114. 120. 109. 105. 100. 97. 97. 101. 107. 111. 108. 102. 93. 88. + 88. 93. 100. 105. 103. 97. 95. 96. 94. 88. 88. 92. 32. 32. 30. 39. + 72. 118. 152. 164. 176. 172. 162. 142. 102. 51. 38. 63. 110. 140. + 160. 168. 177. 179. 173. 173. 175. 178. 179. 175. 171. 166. 156. + 145. 127. 109. 58. 58. 38. 44. 48. 54. 51. 45. 48. 49. 42. 46. 53. + 50. 59. 45. 51. 79. 83. 61. 46. 51. 61. 61. 33. 62. 59. 52. 50. 39. + 39. 69. 53. 52. 95. 87. 50. 56. 44. 53. 78. 115. 122. 95. 138. 105. + 121. 111. 120. 73. 35. 56. 92. 42. 41. 88. 27. 38. 89. 58. 59. 120. + 108. 104. 93. 78. 63. 55. 56. 60. 50. 54. 64. 78. 90. 101. 114. 125. + 122. 130. 128. 121. 102. 63. 59. 99. 107. 120. 131. 133. 132. 134. + 135. 135. 141. 141. 141. 140. 139. 138. 137. 136. 131. 132. 134. + 136. 138. 140. 142. 143. 143. 144. 145. 148. 150. 152. 154. 155. + 158. 159. 161. 163. 165. 167. 169. 170. 177. 180. 184. 187. 189. + 192. 196. 198. 201. 203. 205. 206. 206. 207. 209. 211. 212. 221. + 206. 219. 223. 204. 144. 27. 83. 138. 137. 142. 140. 150. 148. 151. + 143. 143. 142. 141. 140. 140. 139. 139. 139. 140. 140. 140. 139. + 136. 133. 130. 125. 131. 128. 124. 128. 139. 170. 210. 211. 212. + 208. 202. 204. 212. 218. 220. 216. 206. 189. 167. 138. 116. 113. + 121. 108. 104. 99. 95. 96. 100. 105. 109. 101. 95. 88. 85. 87. 94. + 101. 106. 102. 95. 92. 94. 93. 89. 90. 96. 34. 32. 36. 42. 62. 108. + 150. 162. 172. 173. 167. 148. 104. 50. 41. 73. 107. 138. 158. 165. + 174. 177. 175. 178. 180. 178. 180. 182. 174. 158. 147. 145. 138. + 103. 51. 39. 50. 53. 57. 40. 37. 51. 56. 46. 40. 48. 58. 60. 49. 51. + 59. 68. 70. 62. 55. 52. 48. 48. 50. 62. 64. 44. 33. 46. 37. 73. 36. + 44. 105. 80. 38. 54. 81. 80. 84. 102. 122. 119. 110. 114. 98. 141. + 119. 136. 48. 37. 105. 46. 63. 43. 44. 52. 65. 61. 49. 71. 55. 66. + 86. 95. 80. 54. 44. 49. 46. 57. 70. 80. 94. 109. 121. 125. 131. 129. + 124. 130. 87. 53. 86. 94. 111. 126. 135. 131. 131. 138. 140. 135. + 138. 137. 137. 140. 143. 143. 139. 135. 134. 135. 136. 137. 138. + 139. 139. 139. 140. 143. 146. 147. 149. 150. 153. 156. 158. 159. + 161. 163. 165. 168. 170. 170. 174. 178. 183. 187. 190. 192. 195. + 197. 201. 202. 204. 205. 207. 207. 208. 208. 210. 221. 207. 215. + 213. 219. 179. 31. 90. 129. 143. 140. 149. 149. 141. 147. 141. 143. + 144. 144. 142. 141. 142. 142. 139. 140. 141. 140. 138. 135. 131. + 129. 127. 128. 130. 129. 126. 137. 169. 200. 206. 211. 209. 202. + 201. 209. 216. 218. 211. 208. 188. 152. 126. 117. 114. 110. 110. + 109. 102. 94. 94. 101. 103. 99. 87. 86. 86. 90. 95. 100. 103. 104. + 97. 101. 100. 93. 88. 92. 98. 101. 36. 33. 36. 41. 60. 105. 148. + 161. 171. 170. 164. 146. 106. 54. 43. 71. 106. 137. 158. 165. 174. + 177. 175. 178. 180. 178. 179. 180. 173. 158. 148. 146. 142. 107. 52. + 51. 52. 52. 50. 39. 44. 44. 40. 39. 52. 68. 70. 61. 44. 46. 54. 64. + 66. 61. 56. 56. 46. 47. 48. 58. 66. 51. 35. 38. 58. 47. 41. 81. 82. + 69. 85. 55. 89. 88. 86. 85. 93. 110. 120. 119. 92. 108. 121. 139. + 103. 54. 102. 38. 44. 39. 54. 55. 55. 59. 54. 64. 55. 56. 65. 72. + 65. 48. 41. 45. 50. 62. 75. 86. 97. 110. 120. 123. 128. 126. 128. + 121. 79. 58. 86. 100. 113. 127. 135. 132. 132. 138. 140. 136. 139. + 138. 138. 140. 142. 142. 138. 135. 134. 135. 136. 137. 138. 138. + 139. 139. 140. 143. 146. 147. 148. 150. 153. 155. 157. 158. 160. + 162. 164. 167. 168. 169. 172. 176. 181. 185. 188. 190. 193. 196. + 200. 201. 203. 205. 206. 207. 208. 208. 209. 219. 207. 216. 214. + 219. 190. 64. 95. 133. 146. 141. 149. 152. 145. 147. 141. 143. 144. + 143. 141. 139. 139. 139. 140. 140. 141. 141. 139. 136. 133. 132. + 128. 129. 132. 131. 128. 134. 156. 179. 198. 202. 202. 200. 203. + 213. 219. 219. 211. 206. 184. 149. 124. 117. 114. 110. 109. 106. 98. + 92. 95. 101. 101. 95. 78. 83. 90. 97. 101. 102. 102. 101. 93. 98. + 98. 93. 92. 95. 97. 97. 39. 35. 36. 39. 55. 101. 144. 159. 171. 169. + 162. 147. 111. 62. 48. 71. 105. 136. 157. 164. 174. 177. 175. 177. + 179. 177. 178. 178. 171. 160. 150. 147. 150. 115. 54. 67. 53. 52. + 40. 39. 37. 43. 51. 61. 75. 80. 66. 46. 41. 45. 53. 61. 62. 57. 54. + 56. 53. 54. 48. 51. 63. 59. 45. 40. 63. 42. 52. 94. 65. 59. 107. 73. + 56. 83. 116. 116. 101. 114. 129. 116. 86. 71. 91. 128. 129. 86. 104. + 62. 67. 38. 52. 62. 53. 54. 53. 60. 62. 53. 50. 54. 54. 48. 45. 48. + 55. 68. 83. 93. 102. 112. 120. 122. 124. 123. 133. 105. 67. 65. 85. + 108. 117. 129. 136. 134. 134. 140. 141. 138. 141. 140. 140. 141. + 142. 141. 138. 135. 135. 135. 136. 137. 137. 138. 139. 139. 140. + 143. 146. 147. 148. 150. 152. 155. 155. 156. 158. 160. 163. 165. + 167. 168. 171. 174. 179. 183. 185. 188. 191. 194. 199. 200. 202. + 204. 206. 207. 208. 208. 210. 214. 207. 217. 213. 218. 204. 113. + 101. 136. 149. 139. 141. 149. 146. 143. 145. 146. 148. 147. 144. + 142. 142. 143. 140. 140. 140. 140. 139. 136. 134. 132. 129. 131. + 135. 135. 132. 132. 142. 154. 179. 182. 186. 193. 204. 215. 219. + 217. 210. 201. 176. 142. 120. 114. 111. 107. 106. 101. 94. 91. 97. + 101. 96. 87. 69. 80. 95. 105. 107. 103. 99. 96. 89. 93. 95. 94. 96. + 99. 96. 90. 41. 36. 36. 36. 51. 95. 140. 156. 172. 170. 161. 148. + 118. 72. 55. 72. 104. 135. 156. 164. 173. 176. 174. 177. 178. 177. + 177. 175. 170. 161. 152. 147. 159. 124. 58. 81. 54. 51. 34. 44. 40. + 59. 76. 80. 74. 64. 51. 39. 43. 48. 57. 64. 61. 53. 50. 53. 62. 65. + 54. 46. 57. 64. 57. 52. 45. 66. 70. 66. 60. 59. 79. 100. 36. 59. + 112. 135. 122. 128. 133. 106. 95. 68. 65. 124. 121. 121. 106. 92. + 120. 43. 39. 65. 59. 48. 47. 61. 63. 53. 47. 48. 50. 48. 47. 50. 57. + 72. 89. 99. 107. 115. 120. 122. 122. 123. 132. 88. 57. 73. 86. 115. + 122. 131. 137. 136. 137. 141. 142. 139. 142. 142. 142. 142. 141. + 140. 138. 136. 136. 136. 136. 136. 137. 138. 138. 139. 141. 143. + 145. 147. 148. 149. 152. 154. 153. 154. 156. 158. 161. 163. 165. + 166. 170. 173. 178. 181. 184. 187. 191. 193. 197. 198. 201. 203. + 205. 207. 208. 208. 211. 211. 208. 217. 211. 214. 213. 160. 108. + 137. 148. 132. 125. 134. 139. 136. 142. 144. 146. 147. 146. 145. + 146. 147. 142. 141. 141. 140. 138. 135. 133. 132. 132. 135. 138. + 139. 137. 136. 138. 141. 153. 157. 167. 183. 203. 216. 218. 214. + 207. 193. 165. 134. 115. 110. 107. 103. 100. 95. 91. 94. 100. 99. + 89. 78. 69. 83. 100. 110. 108. 101. 95. 92. 87. 90. 92. 95. 99. 100. + 92. 81. 41. 37. 36. 35. 47. 91. 137. 153. 169. 168. 160. 148. 121. + 77. 58. 70. 102. 134. 155. 163. 172. 176. 174. 177. 177. 177. 176. + 174. 170. 163. 152. 144. 163. 128. 65. 87. 56. 50. 35. 49. 58. 69. + 74. 65. 50. 43. 46. 50. 43. 50. 61. 67. 62. 54. 52. 56. 60. 68. 60. + 49. 57. 63. 57. 53. 34. 82. 91. 42. 48. 62. 56. 115. 71. 45. 59. 88. + 93. 108. 124. 114. 83. 52. 51. 106. 119. 149. 148. 145. 120. 46. 40. + 60. 52. 46. 48. 61. 52. 49. 46. 46. 45. 42. 43. 46. 58. 75. 93. 104. + 110. 117. 122. 124. 123. 124. 123. 73. 54. 79. 91. 120. 127. 132. + 136. 137. 138. 141. 142. 140. 143. 144. 144. 143. 141. 140. 139. + 139. 137. 137. 136. 136. 136. 137. 138. 139. 141. 143. 145. 147. + 147. 148. 151. 153. 152. 153. 155. 157. 159. 162. 164. 164. 171. + 173. 177. 180. 183. 186. 191. 194. 195. 196. 199. 202. 205. 207. + 208. 209. 212. 210. 210. 215. 208. 210. 216. 192. 123. 138. 141. + 122. 107. 115. 127. 125. 129. 132. 136. 139. 141. 143. 145. 147. + 146. 145. 144. 142. 140. 138. 136. 134. 135. 139. 142. 143. 143. + 142. 141. 139. 134. 140. 156. 181. 206. 218. 218. 213. 206. 187. + 156. 129. 114. 109. 105. 101. 92. 91. 92. 98. 100. 94. 83. 74. 79. + 90. 103. 108. 104. 96. 91. 89. 87. 90. 92. 95. 99. 98. 86. 73. 39. + 36. 36. 34. 45. 88. 133. 151. 164. 165. 160. 147. 121. 79. 58. 67. + 101. 133. 154. 162. 172. 175. 174. 177. 176. 178. 177. 174. 171. + 164. 152. 139. 156. 125. 72. 86. 60. 48. 39. 50. 55. 56. 55. 51. 47. + 45. 46. 47. 44. 51. 62. 67. 62. 55. 59. 67. 51. 61. 58. 53. 59. 59. + 48. 43. 42. 78. 93. 46. 38. 59. 66. 113. 101. 60. 48. 56. 45. 52. + 94. 131. 101. 49. 52. 70. 101. 121. 169. 160. 65. 45. 56. 50. 37. + 49. 54. 55. 45. 47. 48. 47. 44. 43. 46. 50. 62. 80. 99. 108. 113. + 119. 124. 126. 123. 124. 104. 63. 59. 84. 101. 124. 131. 133. 136. + 138. 139. 141. 141. 140. 143. 144. 144. 143. 141. 140. 141. 142. + 138. 138. 136. 135. 135. 136. 138. 139. 141. 143. 145. 146. 146. + 147. 150. 152. 152. 152. 154. 157. 159. 161. 163. 164. 170. 173. + 176. 179. 181. 185. 190. 193. 193. 195. 198. 201. 204. 207. 208. + 209. 212. 210. 214. 214. 208. 210. 215. 208. 149. 137. 126. 109. 93. + 100. 112. 110. 117. 121. 126. 131. 135. 139. 143. 146. 146. 145. + 144. 143. 142. 141. 140. 139. 138. 143. 147. 146. 146. 146. 143. + 139. 129. 137. 158. 189. 213. 222. 219. 214. 203. 180. 149. 125. + 113. 108. 102. 97. 87. 90. 95. 99. 95. 85. 79. 78. 92. 97. 103. 103. + 98. 93. 89. 88. 92. 94. 95. 95. 95. 91. 78. 65. 36. 34. 35. 34. 44. + 86. 131. 149. 163. 167. 164. 151. 123. 81. 60. 69. 100. 132. 153. + 161. 171. 175. 173. 177. 175. 178. 178. 175. 172. 166. 150. 135. + 142. 117. 78. 82. 66. 46. 42. 45. 44. 46. 49. 52. 53. 50. 45. 43. + 51. 56. 62. 63. 56. 53. 63. 77. 55. 56. 48. 47. 56. 54. 41. 37. 46. + 80. 64. 52. 53. 50. 81. 112. 112. 85. 70. 63. 39. 25. 60. 114. 130. + 67. 61. 80. 83. 78. 129. 106. 33. 47. 63. 45. 37. 54. 52. 50. 48. + 48. 46. 44. 45. 50. 57. 61. 70. 87. 105. 113. 115. 119. 125. 127. + 121. 122. 81. 56. 69. 89. 114. 129. 133. 133. 134. 138. 140. 140. + 140. 140. 142. 144. 145. 143. 141. 140. 142. 145. 139. 138. 136. + 135. 135. 136. 138. 139. 141. 143. 145. 146. 146. 147. 149. 151. + 152. 153. 154. 157. 159. 161. 163. 164. 168. 171. 174. 176. 179. + 183. 188. 192. 192. 194. 197. 200. 204. 206. 208. 209. 210. 211. + 217. 213. 210. 215. 215. 214. 176. 132. 102. 91. 82. 88. 97. 89. + 101. 105. 111. 117. 122. 127. 131. 135. 137. 137. 137. 138. 139. + 140. 141. 142. 140. 148. 152. 150. 147. 145. 139. 133. 133. 143. + 167. 198. 219. 222. 216. 212. 195. 169. 137. 116. 108. 103. 95. 88. + 87. 92. 98. 97. 85. 74. 78. 88. 101. 101. 100. 98. 95. 92. 90. 88. + 97. 99. 98. 94. 90. 84. 72. 60. 34. 33. 35. 34. 44. 85. 130. 147. + 165. 172. 169. 156. 127. 85. 64. 72. 100. 131. 153. 161. 171. 175. + 173. 176. 175. 179. 179. 176. 173. 166. 149. 132. 130. 110. 81. 79. + 70. 44. 44. 40. 52. 53. 53. 49. 42. 40. 48. 58. 60. 62. 63. 59. 49. + 48. 62. 80. 68. 57. 38. 36. 50. 50. 41. 41. 41. 94. 30. 47. 80. 42. + 81. 118. 132. 98. 66. 61. 59. 42. 44. 72. 82. 42. 45. 128. 102. 97. + 117. 84. 45. 50. 56. 45. 50. 57. 44. 50. 49. 45. 39. 36. 42. 53. 63. + 67. 76. 93. 110. 116. 116. 120. 125. 127. 119. 121. 67. 53. 76. 92. + 124. 133. 134. 133. 134. 137. 140. 139. 139. 139. 141. 143. 145. + 144. 141. 141. 143. 146. 140. 138. 136. 135. 135. 136. 138. 139. + 141. 143. 145. 146. 146. 147. 149. 151. 152. 153. 154. 157. 159. + 162. 163. 164. 167. 169. 172. 174. 177. 181. 186. 190. 191. 193. + 196. 200. 204. 206. 208. 209. 209. 211. 218. 212. 212. 219. 215. + 216. 191. 126. 83. 76. 74. 81. 85. 72. 83. 87. 93. 99. 104. 109. + 114. 117. 126. 127. 128. 130. 133. 136. 139. 141. 141. 151. 157. + 152. 146. 141. 134. 125. 137. 147. 173. 204. 222. 220. 212. 208. + 186. 160. 127. 108. 102. 96. 86. 78. 88. 94. 100. 94. 77. 67. 78. + 96. 104. 102. 98. 96. 95. 93. 91. 89. 101. 103. 100. 93. 86. 79. 67. + 57. 35. 33. 35. 38. 44. 68. 117. 161. 170. 174. 175. 156. 136. 96. + 54. 67. 96. 128. 150. 159. 169. 174. 172. 176. 177. 173. 178. 180. + 172. 167. 157. 139. 129. 105. 74. 77. 79. 44. 30. 54. 64. 53. 45. + 44. 43. 44. 52. 62. 64. 46. 69. 54. 58. 50. 60. 64. 66. 53. 49. 47. + 42. 46. 50. 44. 47. 49. 48. 84. 62. 102. 102. 100. 130. 146. 86. 50. + 61. 87. 54. 51. 61. 44. 56. 135. 55. 104. 121. 62. 51. 45. 40. 40. + 45. 49. 49. 47. 44. 42. 40. 43. 50. 60. 69. 74. 90. 106. 116. 115. + 114. 117. 119. 116. 124. 81. 49. 60. 87. 107. 123. 137. 133. 134. + 135. 137. 139. 141. 142. 143. 145. 143. 141. 140. 139. 141. 143. + 144. 142. 137. 136. 139. 138. 133. 133. 138. 137. 140. 142. 143. + 143. 144. 147. 149. 151. 152. 153. 155. 157. 159. 161. 161. 167. + 168. 170. 172. 174. 178. 184. 188. 188. 192. 197. 201. 203. 205. + 207. 209. 210. 211. 212. 213. 215. 216. 218. 218. 213. 111. 80. 81. + 78. 85. 72. 72. 73. 78. 84. 88. 89. 90. 94. 97. 97. 103. 111. 115. + 118. 123. 132. 139. 138. 154. 165. 159. 145. 135. 132. 132. 131. + 152. 185. 214. 225. 218. 207. 200. 173. 148. 119. 101. 93. 86. 80. + 77. 88. 97. 93. 75. 66. 76. 91. 99. 106. 98. 94. 95. 93. 89. 91. 96. + 106. 101. 96. 91. 81. 66. 56. 53. 38. 33. 30. 32. 41. 68. 117. 161. + 170. 174. 176. 159. 142. 103. 59. 68. 96. 128. 150. 158. 169. 174. + 173. 176. 177. 173. 179. 181. 173. 167. 156. 137. 118. 115. 83. 85. + 81. 42. 37. 53. 51. 48. 47. 46. 43. 43. 54. 68. 52. 45. 71. 54. 53. + 50. 64. 70. 68. 58. 55. 51. 41. 43. 51. 49. 59. 41. 56. 78. 32. 84. + 114. 88. 117. 145. 133. 89. 69. 51. 55. 80. 70. 87. 89. 128. 60. 69. + 66. 41. 53. 48. 43. 43. 46. 48. 46. 43. 44. 42. 41. 44. 52. 63. 73. + 79. 90. 110. 123. 120. 117. 121. 122. 118. 102. 68. 48. 66. 98. 117. + 128. 136. 134. 135. 136. 137. 139. 140. 141. 142. 143. 143. 142. + 141. 141. 141. 142. 143. 142. 137. 136. 139. 138. 134. 134. 138. + 137. 139. 142. 143. 143. 144. 146. 148. 150. 151. 153. 155. 157. + 159. 160. 161. 166. 168. 170. 171. 173. 178. 183. 187. 187. 191. + 196. 200. 202. 204. 207. 209. 210. 210. 211. 213. 215. 216. 217. + 218. 215. 131. 79. 82. 82. 90. 78. 80. 72. 74. 77. 78. 77. 77. 77. + 77. 81. 86. 91. 94. 97. 103. 113. 120. 139. 146. 152. 151. 150. 150. + 147. 142. 141. 164. 193. 214. 221. 215. 200. 186. 154. 133. 107. 89. + 79. 75. 76. 80. 90. 95. 90. 76. 72. 84. 97. 101. 98. 94. 93. 95. 93. + 90. 92. 98. 107. 101. 95. 89. 79. 65. 56. 54. 41. 34. 28. 29. 38. + 66. 117. 161. 171. 175. 177. 162. 149. 112. 64. 67. 96. 128. 150. + 158. 169. 174. 173. 176. 176. 174. 180. 181. 173. 168. 155. 133. 96. + 122. 87. 88. 78. 37. 49. 51. 44. 41. 41. 45. 49. 52. 58. 65. 43. 46. + 74. 54. 45. 51. 65. 71. 68. 61. 61. 55. 41. 42. 52. 52. 63. 46. 55. + 60. 27. 55. 91. 88. 105. 120. 147. 127. 112. 69. 80. 95. 113. 120. + 72. 57. 38. 44. 47. 63. 54. 50. 46. 45. 47. 46. 43. 39. 43. 42. 42. + 45. 54. 66. 79. 86. 96. 115. 124. 118. 117. 125. 123. 112. 70. 53. + 52. 80. 112. 128. 133. 136. 136. 136. 137. 138. 138. 139. 140. 140. + 141. 142. 142. 143. 143. 142. 142. 142. 142. 138. 137. 138. 137. + 135. 135. 137. 137. 139. 141. 142. 142. 143. 145. 147. 150. 150. + 152. 154. 156. 158. 159. 160. 165. 166. 169. 171. 173. 177. 182. + 186. 187. 190. 196. 199. 201. 203. 206. 208. 209. 210. 211. 212. + 214. 216. 217. 217. 218. 163. 81. 82. 86. 97. 87. 90. 83. 81. 79. + 78. 75. 72. 67. 64. 64. 66. 67. 67. 69. 76. 86. 94. 123. 126. 132. + 144. 161. 171. 166. 155. 155. 181. 205. 215. 218. 215. 195. 172. + 136. 116. 92. 74. 65. 64. 72. 82. 88. 89. 85. 78. 82. 96. 103. 102. + 90. 90. 92. 94. 92. 91. 95. 102. 108. 100. 92. 85. 74. 62. 54. 54. + 42. 39. 37. 36. 40. 65. 114. 160. 171. 176. 179. 165. 155. 119. 67. + 64. 95. 127. 149. 158. 169. 174. 173. 177. 176. 175. 181. 181. 174. + 169. 154. 128. 79. 124. 82. 80. 70. 35. 59. 47. 47. 38. 34. 43. 57. + 65. 61. 55. 42. 50. 73. 54. 41. 55. 62. 64. 65. 59. 61. 57. 46. 46. + 52. 49. 50. 61. 49. 41. 52. 36. 44. 90. 107. 105. 134. 142. 135. + 111. 112. 100. 95. 104. 73. 49. 52. 46. 42. 57. 51. 49. 47. 47. 47. + 45. 41. 38. 40. 41. 43. 48. 57. 71. 85. 94. 108. 116. 116. 111. 118. + 126. 113. 89. 43. 47. 66. 98. 124. 133. 135. 136. 137. 137. 138. + 138. 138. 138. 139. 139. 139. 140. 142. 144. 144. 143. 142. 141. + 141. 139. 138. 138. 137. 136. 136. 137. 137. 139. 141. 142. 141. + 142. 144. 146. 148. 149. 151. 153. 155. 157. 158. 159. 162. 165. + 167. 170. 172. 175. 180. 183. 185. 189. 194. 198. 200. 202. 205. + 207. 208. 209. 210. 212. 213. 215. 216. 217. 219. 192. 91. 82. 89. + 101. 96. 99. 97. 93. 88. 84. 81. 76. 68. 62. 59. 57. 53. 49. 49. 54. + 62. 69. 88. 100. 122. 151. 178. 189. 178. 161. 158. 187. 209. 212. + 214. 214. 190. 158. 122. 102. 79. 65. 60. 63. 73. 83. 79. 80. 80. + 84. 95. 106. 107. 100. 87. 88. 90. 89. 88. 91. 98. 105. 106. 97. 88. + 79. 69. 58. 52. 53. 46. 50. 55. 54. 50. 66. 112. 157. 171. 178. 181. + 167. 159. 123. 69. 63. 95. 127. 149. 158. 170. 175. 174. 178. 175. + 176. 182. 182. 175. 171. 152. 122. 82. 129. 81. 68. 60. 35. 60. 41. + 46. 45. 45. 49. 56. 61. 59. 55. 45. 49. 64. 53. 42. 63. 62. 59. 62. + 54. 56. 58. 52. 52. 52. 43. 34. 64. 56. 41. 57. 43. 34. 65. 92. 106. + 131. 148. 119. 124. 118. 101. 81. 91. 109. 85. 51. 34. 42. 47. 46. + 46. 46. 47. 47. 45. 42. 39. 39. 41. 46. 53. 62. 76. 90. 100. 115. + 115. 113. 115. 126. 123. 92. 56. 35. 56. 88. 115. 128. 132. 134. + 136. 138. 138. 138. 138. 138. 138. 138. 138. 138. 140. 142. 145. + 145. 144. 142. 140. 141. 141. 139. 137. 137. 137. 137. 137. 137. + 138. 140. 141. 140. 141. 143. 145. 147. 148. 149. 151. 153. 155. + 157. 158. 160. 163. 166. 169. 171. 174. 178. 181. 184. 188. 193. + 197. 199. 201. 203. 205. 207. 208. 209. 211. 212. 214. 215. 216. + 218. 211. 115. 83. 89. 100. 101. 103. 102. 98. 93. 89. 86. 81. 73. + 67. 63. 59. 51. 44. 39. 41. 45. 50. 56. 88. 133. 173. 197. 198. 178. + 158. 159. 188. 208. 209. 211. 210. 181. 143. 104. 84. 64. 59. 64. + 71. 78. 84. 69. 73. 80. 92. 105. 111. 104. 93. 88. 88. 87. 85. 85. + 92. 101. 108. 102. 93. 83. 75. 65. 55. 51. 53. 59. 65. 73. 73. 66. + 74. 112. 152. 170. 180. 185. 170. 161. 128. 73. 66. 94. 126. 149. + 158. 170. 175. 174. 178. 175. 177. 183. 182. 175. 172. 151. 117. 97. + 135. 89. 63. 53. 38. 56. 41. 42. 55. 64. 57. 46. 45. 53. 61. 47. 45. + 54. 55. 46. 71. 62. 60. 62. 53. 55. 58. 53. 53. 51. 39. 32. 52. 64. + 57. 39. 63. 62. 31. 50. 82. 115. 147. 127. 143. 117. 84. 116. 94. + 116. 89. 31. 34. 59. 55. 42. 43. 44. 44. 44. 43. 42. 41. 39. 44. 52. + 60. 70. 82. 97. 107. 115. 114. 117. 125. 126. 106. 68. 36. 46. 75. + 109. 126. 129. 130. 133. 137. 137. 137. 138. 138. 138. 138. 139. + 139. 138. 139. 142. 144. 145. 144. 143. 141. 140. 142. 141. 137. + 136. 138. 138. 136. 136. 138. 140. 140. 139. 140. 141. 143. 146. + 147. 148. 150. 152. 154. 156. 156. 158. 161. 165. 168. 170. 173. + 176. 179. 183. 187. 192. 196. 198. 200. 202. 204. 207. 207. 208. + 210. 212. 213. 214. 215. 216. 218. 149. 86. 88. 97. 104. 105. 105. + 103. 100. 97. 93. 88. 82. 78. 71. 65. 56. 47. 40. 37. 37. 38. 43. + 90. 152. 196. 209. 198. 174. 154. 172. 196. 213. 213. 211. 201. 165. + 123. 80. 64. 53. 57. 69. 77. 80. 82. 67. 74. 86. 99. 108. 107. 96. + 86. 86. 87. 84. 82. 86. 97. 105. 108. 99. 90. 81. 73. 64. 56. 53. + 55. 79. 81. 85. 86. 81. 87. 115. 146. 166. 180. 187. 172. 164. 133. + 81. 75. 94. 126. 148. 158. 170. 175. 175. 178. 174. 178. 184. 182. + 176. 173. 150. 112. 103. 132. 98. 61. 48. 42. 50. 48. 47. 60. 65. + 55. 42. 41. 50. 57. 51. 44. 50. 60. 48. 71. 58. 62. 65. 58. 59. 58. + 49. 48. 48. 41. 44. 47. 49. 66. 41. 76. 66. 34. 30. 51. 82. 116. + 138. 155. 134. 96. 110. 86. 117. 107. 46. 54. 57. 39. 41. 42. 42. + 42. 41. 40. 40. 40. 41. 49. 60. 69. 78. 90. 103. 112. 116. 115. 120. + 121. 102. 70. 49. 44. 69. 95. 121. 130. 130. 132. 135. 136. 136. + 137. 137. 138. 138. 139. 139. 140. 138. 139. 141. 143. 144. 144. + 143. 143. 140. 143. 142. 137. 136. 139. 139. 136. 136. 138. 140. + 140. 139. 139. 141. 142. 145. 146. 147. 149. 151. 153. 155. 156. + 156. 160. 164. 167. 169. 172. 175. 177. 182. 186. 191. 195. 197. + 199. 201. 203. 206. 207. 208. 209. 211. 213. 214. 214. 216. 217. + 185. 90. 88. 94. 107. 105. 106. 107. 107. 104. 98. 93. 90. 89. 79. + 74. 65. 56. 48. 43. 38. 36. 41. 94. 161. 203. 210. 194. 172. 157. + 185. 202. 213. 211. 201. 178. 131. 87. 62. 55. 54. 63. 72. 76. 75. + 75. 74. 82. 95. 105. 106. 98. 87. 80. 81. 82. 81. 83. 92. 105. 109. + 106. 98. 90. 81. 75. 67. 59. 57. 59. 95. 91. 90. 91. 91. 96. 118. + 141. 164. 180. 189. 174. 166. 136. 87. 83. 94. 126. 148. 158. 170. + 175. 175. 179. 174. 178. 185. 182. 176. 173. 149. 110. 98. 123. 101. + 59. 46. 45. 48. 56. 59. 59. 54. 46. 45. 50. 50. 45. 57. 47. 52. 66. + 48. 66. 52. 61. 70. 64. 64. 58. 44. 41. 47. 45. 57. 53. 23. 63. 66. + 77. 43. 62. 49. 49. 67. 73. 115. 132. 152. 144. 90. 90. 130. 118. + 43. 45. 43. 44. 41. 42. 42. 41. 39. 37. 38. 38. 44. 53. 65. 75. 84. + 95. 107. 116. 120. 118. 119. 108. 72. 37. 39. 64. 87. 107. 125. 129. + 130. 135. 137. 135. 136. 136. 137. 138. 138. 139. 140. 140. 139. + 140. 141. 142. 143. 144. 144. 144. 140. 143. 142. 136. 136. 140. + 140. 136. 136. 138. 139. 139. 138. 138. 140. 142. 145. 145. 147. + 149. 151. 153. 154. 155. 156. 159. 163. 167. 169. 171. 174. 177. + 182. 186. 191. 194. 197. 198. 201. 203. 206. 206. 208. 209. 211. + 212. 213. 214. 216. 214. 207. 93. 88. 92. 108. 105. 103. 106. 107. + 104. 97. 92. 90. 91. 85. 80. 72. 64. 57. 50. 43. 39. 40. 94. 159. + 199. 205. 191. 174. 163. 187. 198. 204. 199. 183. 149. 95. 49. 57. + 57. 62. 70. 74. 71. 68. 68. 82. 91. 102. 108. 103. 91. 81. 77. 75. + 78. 80. 85. 98. 112. 112. 105. 98. 90. 83. 77. 70. 62. 60. 62. 83. + 93. 92. 88. 98. 110. 127. 147. 170. 179. 185. 181. 168. 144. 104. + 70. 100. 121. 145. 161. 170. 175. 177. 175. 174. 178. 180. 188. 176. + 167. 151. 98. 111. 109. 103. 60. 48. 58. 40. 48. 43. 54. 46. 46. 44. + 43. 57. 52. 59. 51. 46. 52. 46. 45. 61. 61. 66. 64. 41. 64. 72. 41. + 43. 44. 45. 70. 60. 38. 54. 71. 63. 50. 59. 74. 56. 71. 73. 65. 109. + 139. 112. 128. 66. 38. 54. 43. 42. 44. 51. 46. 42. 41. 38. 36. 40. + 47. 42. 56. 74. 85. 91. 101. 115. 127. 120. 119. 102. 68. 36. 33. + 61. 90. 117. 121. 125. 129. 130. 132. 134. 136. 136. 137. 138. 139. + 139. 139. 138. 138. 137. 138. 141. 143. 144. 143. 142. 141. 143. + 143. 142. 140. 139. 138. 137. 136. 136. 136. 137. 138. 139. 139. + 139. 139. 144. 145. 147. 148. 149. 150. 154. 156. 156. 159. 161. + 163. 164. 166. 170. 173. 179. 183. 187. 191. 194. 198. 202. 205. + 205. 206. 207. 209. 211. 212. 212. 212. 213. 214. 218. 138. 76. 90. + 92. 108. 107. 108. 108. 106. 101. 97. 95. 94. 84. 82. 78. 70. 61. + 54. 49. 47. 55. 91. 151. 192. 198. 195. 192. 184. 189. 194. 199. + 186. 142. 89. 56. 50. 53. 58. 65. 70. 72. 72. 73. 74. 92. 102. 108. + 102. 88. 79. 76. 77. 78. 78. 83. 95. 107. 112. 109. 103. 91. 88. 83. + 75. 68. 63. 62. 62. 77. 92. 97. 98. 107. 117. 132. 153. 171. 180. + 184. 179. 167. 145. 109. 77. 100. 121. 145. 161. 169. 175. 177. 175. + 174. 180. 181. 186. 175. 169. 152. 94. 117. 109. 93. 51. 44. 55. 41. + 47. 45. 52. 45. 50. 48. 43. 57. 56. 49. 45. 47. 53. 49. 52. 63. 60. + 64. 56. 49. 72. 77. 50. 45. 55. 36. 54. 78. 78. 32. 60. 77. 58. 61. + 58. 98. 55. 87. 97. 94. 72. 129. 136. 88. 50. 53. 52. 45. 40. 45. + 43. 43. 45. 45. 43. 46. 51. 73. 75. 78. 82. 88. 98. 110. 118. 116. + 92. 60. 40. 41. 61. 86. 103. 119. 122. 126. 129. 131. 132. 134. 136. + 137. 137. 138. 139. 139. 139. 139. 139. 137. 138. 141. 143. 144. + 143. 142. 141. 144. 144. 143. 141. 140. 139. 138. 137. 137. 137. + 138. 139. 139. 139. 139. 139. 143. 145. 147. 148. 148. 150. 153. + 156. 156. 158. 161. 162. 164. 166. 170. 173. 177. 180. 185. 188. + 191. 195. 199. 203. 204. 205. 207. 209. 210. 211. 212. 212. 211. + 219. 213. 165. 81. 90. 91. 104. 105. 107. 107. 106. 101. 98. 96. 95. + 89. 87. 83. 77. 71. 66. 63. 62. 59. 88. 143. 186. 200. 206. 207. + 198. 190. 177. 161. 139. 106. 71. 54. 55. 56. 63. 69. 70. 68. 70. + 77. 84. 99. 103. 104. 96. 84. 77. 77. 79. 78. 82. 90. 102. 110. 111. + 105. 98. 94. 87. 78. 70. 66. 65. 65. 65. 70. 90. 102. 107. 115. 119. + 131. 151. 169. 177. 181. 175. 164. 145. 112. 83. 100. 120. 144. 160. + 169. 175. 177. 176. 175. 183. 182. 183. 174. 171. 153. 89. 124. 111. + 85. 45. 41. 53. 45. 49. 48. 51. 45. 56. 54. 43. 56. 59. 50. 44. 47. + 48. 47. 60. 72. 71. 67. 47. 60. 81. 82. 60. 42. 58. 48. 54. 86. 83. + 48. 56. 79. 59. 58. 62. 104. 53. 84. 126. 121. 64. 76. 82. 78. 48. + 37. 49. 47. 48. 46. 43. 41. 41. 39. 38. 42. 48. 64. 70. 82. 98. 110. + 114. 108. 102. 66. 50. 37. 47. 74. 100. 111. 110. 121. 124. 128. + 130. 131. 133. 135. 137. 137. 138. 139. 140. 140. 140. 140. 139. + 137. 139. 141. 142. 143. 143. 142. 141. 145. 145. 144. 143. 142. + 141. 140. 139. 138. 138. 138. 139. 139. 139. 139. 140. 143. 144. + 146. 147. 148. 149. 153. 155. 156. 158. 160. 162. 163. 166. 169. + 172. 174. 177. 182. 185. 188. 192. 196. 199. 203. 204. 206. 208. + 210. 211. 212. 212. 209. 222. 208. 197. 97. 84. 91. 98. 103. 104. + 106. 105. 102. 99. 97. 97. 95. 92. 88. 84. 80. 79. 79. 79. 79. 99. + 144. 186. 206. 213. 210. 195. 174. 148. 116. 91. 72. 57. 54. 60. 63. + 68. 72. 70. 68. 73. 87. 99. 106. 104. 97. 87. 78. 73. 75. 79. 80. + 88. 100. 110. 113. 109. 101. 94. 95. 85. 72. 64. 64. 67. 67. 66. 62. + 84. 101. 110. 114. 112. 120. 140. 163. 173. 178. 173. 162. 142. 110. + 82. 100. 120. 143. 159. 168. 175. 177. 177. 176. 185. 183. 181. 173. + 173. 155. 88. 121. 112. 82. 47. 42. 49. 49. 54. 51. 51. 46. 61. 58. + 41. 51. 58. 65. 49. 49. 41. 42. 66. 81. 88. 76. 42. 65. 86. 88. 71. + 39. 49. 46. 66. 88. 59. 77. 50. 71. 86. 47. 71. 62. 78. 69. 116. + 147. 102. 62. 57. 87. 69. 38. 40. 37. 51. 48. 42. 37. 35. 35. 37. + 47. 57. 78. 83. 92. 100. 99. 85. 63. 47. 35. 43. 59. 81. 102. 115. + 117. 115. 124. 126. 129. 131. 132. 133. 135. 138. 137. 138. 139. + 140. 140. 140. 140. 140. 138. 139. 140. 142. 143. 143. 142. 142. + 146. 146. 145. 144. 143. 142. 142. 141. 140. 140. 139. 139. 139. + 140. 140. 140. 142. 144. 146. 146. 147. 149. 152. 155. 155. 157. + 159. 161. 162. 165. 169. 172. 173. 176. 180. 184. 186. 190. 194. + 197. 202. 203. 205. 207. 209. 211. 211. 211. 211. 220. 208. 215. + 123. 72. 95. 91. 99. 101. 104. 104. 102. 100. 100. 100. 97. 94. 89. + 86. 86. 87. 88. 89. 93. 107. 147. 190. 211. 215. 200. 175. 138. 115. + 89. 72. 63. 59. 60. 65. 72. 72. 71. 71. 75. 85. 100. 112. 108. 100. + 90. 80. 72. 68. 70. 76. 85. 95. 107. 115. 114. 107. 100. 95. 92. 80. + 66. 62. 65. 69. 67. 64. 53. 74. 93. 104. 109. 105. 112. 133. 158. + 171. 179. 175. 164. 143. 110. 82. 99. 119. 142. 157. 167. 174. 178. + 178. 177. 185. 183. 182. 173. 173. 157. 95. 104. 104. 77. 50. 43. + 43. 49. 55. 52. 53. 48. 63. 59. 40. 48. 53. 77. 50. 52. 41. 42. 67. + 78. 93. 81. 40. 63. 88. 96. 89. 52. 45. 31. 61. 81. 70. 58. 38. 66. + 117. 67. 58. 41. 90. 74. 97. 131. 125. 82. 49. 73. 72. 45. 40. 36. + 52. 43. 40. 39. 42. 45. 49. 58. 67. 80. 76. 70. 61. 53. 46. 43. 42. + 68. 79. 92. 101. 105. 109. 117. 123. 126. 128. 130. 131. 131. 132. + 135. 137. 137. 138. 139. 140. 140. 140. 139. 139. 138. 139. 140. + 141. 142. 142. 143. 143. 146. 146. 146. 145. 144. 144. 143. 143. + 142. 141. 140. 139. 139. 140. 141. 141. 141. 143. 145. 146. 146. + 148. 151. 154. 154. 156. 159. 160. 161. 164. 168. 171. 173. 176. + 180. 183. 186. 189. 193. 196. 200. 202. 204. 206. 209. 210. 211. + 211. 214. 214. 212. 215. 155. 66. 98. 87. 95. 98. 101. 103. 102. + 102. 102. 103. 101. 97. 92. 91. 92. 94. 95. 95. 88. 101. 140. 182. + 203. 202. 178. 146. 101. 90. 78. 71. 68. 68. 70. 74. 78. 73. 70. 75. + 87. 100. 110. 115. 103. 93. 83. 76. 68. 63. 67. 75. 91. 100. 111. + 115. 112. 105. 100. 98. 84. 73. 63. 62. 68. 70. 64. 57. 46. 63. 79. + 93. 101. 100. 109. 133. 156. 170. 181. 179. 167. 147. 116. 89. 99. + 118. 141. 156. 166. 174. 178. 178. 179. 182. 181. 184. 174. 170. + 160. 108. 82. 90. 66. 50. 44. 37. 48. 52. 50. 55. 52. 64. 59. 43. + 49. 49. 81. 45. 53. 47. 48. 66. 67. 88. 75. 41. 57. 91. 105. 106. + 81. 53. 50. 47. 60. 103. 30. 43. 59. 90. 118. 52. 59. 68. 89. 108. + 121. 148. 109. 56. 46. 52. 44. 41. 40. 46. 43. 43. 47. 51. 51. 47. + 48. 52. 45. 45. 45. 44. 48. 59. 77. 90. 97. 102. 108. 113. 117. 120. + 124. 127. 127. 129. 130. 130. 130. 131. 134. 137. 136. 137. 138. + 138. 139. 139. 138. 138. 139. 139. 140. 141. 141. 142. 143. 143. + 146. 146. 145. 145. 144. 144. 144. 143. 144. 143. 141. 140. 139. + 140. 141. 142. 140. 142. 144. 145. 145. 147. 150. 153. 153. 155. + 158. 159. 161. 163. 167. 170. 174. 177. 180. 183. 185. 188. 192. + 195. 199. 200. 203. 205. 208. 210. 211. 211. 215. 211. 215. 212. + 183. 77. 94. 85. 92. 95. 99. 102. 102. 103. 104. 106. 106. 102. 98. + 98. 101. 104. 104. 103. 94. 101. 130. 162. 172. 165. 138. 106. 84. + 80. 76. 74. 73. 75. 79. 81. 78. 74. 74. 83. 98. 109. 111. 108. 92. + 83. 76. 72. 66. 62. 70. 83. 99. 106. 113. 115. 111. 104. 99. 97. 76. + 68. 61. 62. 67. 68. 60. 52. 44. 55. 65. 79. 90. 92. 104. 129. 153. + 168. 178. 176. 167. 150. 123. 99. 99. 118. 141. 156. 165. 174. 178. + 179. 181. 179. 179. 188. 175. 167. 162. 122. 68. 78. 53. 47. 47. 39. + 51. 50. 45. 57. 55. 64. 60. 50. 56. 50. 90. 42. 52. 51. 51. 64. 60. + 92. 63. 43. 52. 91. 107. 113. 107. 62. 64. 41. 59. 107. 58. 48. 47. + 55. 119. 78. 71. 58. 84. 124. 125. 138. 136. 103. 67. 58. 46. 37. + 44. 37. 50. 48. 47. 48. 44. 39. 40. 44. 50. 57. 65. 72. 77. 85. 94. + 102. 104. 109. 117. 124. 128. 129. 128. 127. 128. 129. 130. 129. + 129. 130. 133. 136. 135. 135. 136. 137. 138. 138. 137. 137. 139. + 139. 140. 140. 141. 142. 143. 144. 145. 145. 145. 144. 144. 144. + 144. 143. 145. 144. 142. 140. 139. 140. 142. 143. 140. 141. 143. + 144. 145. 146. 150. 152. 153. 155. 157. 159. 160. 163. 166. 170. + 173. 176. 179. 182. 184. 187. 191. 194. 198. 199. 202. 205. 207. + 209. 210. 211. 212. 213. 212. 216. 200. 102. 84. 85. 89. 93. 97. + 101. 103. 104. 106. 108. 107. 103. 101. 104. 109. 113. 112. 110. + 109. 107. 120. 134. 133. 125. 106. 82. 84. 83. 81. 81. 83. 84. 82. + 78. 72. 74. 81. 93. 105. 108. 102. 95. 82. 74. 70. 69. 64. 64. 79. + 99. 106. 110. 115. 116. 112. 103. 95. 90. 71. 65. 60. 60. 64. 63. + 57. 50. 46. 52. 57. 69. 81. 83. 96. 122. 149. 163. 173. 171. 163. + 149. 126. 105. 98. 118. 140. 155. 165. 174. 178. 179. 182. 177. 178. + 190. 176. 165. 163. 131. 65. 73. 44. 44. 51. 44. 56. 50. 41. 58. 57. + 64. 62. 55. 62. 52. 103. 44. 50. 49. 49. 62. 61. 103. 53. 46. 50. + 90. 103. 111. 118. 64. 37. 41. 85. 90. 110. 36. 39. 65. 64. 110. 63. + 76. 68. 117. 111. 83. 97. 106. 76. 61. 43. 34. 59. 53. 52. 46. 41. + 39. 40. 43. 53. 64. 69. 73. 80. 88. 94. 100. 106. 109. 118. 123. + 126. 123. 117. 117. 124. 131. 128. 129. 129. 129. 128. 129. 132. + 135. 134. 135. 136. 136. 137. 137. 136. 136. 140. 140. 140. 140. + 141. 142. 143. 144. 145. 144. 144. 144. 144. 144. 143. 143. 146. + 144. 142. 140. 139. 140. 142. 143. 139. 141. 143. 144. 144. 146. + 149. 152. 152. 154. 157. 158. 160. 162. 166. 169. 172. 175. 178. + 181. 183. 186. 189. 192. 197. 199. 201. 204. 207. 209. 210. 211. + 209. 217. 209. 222. 207. 123. 76. 86. 87. 91. 97. 100. 103. 105. + 107. 109. 105. 102. 101. 106. 113. 118. 117. 114. 114. 106. 109. + 113. 109. 107. 100. 85. 88. 88. 87. 90. 94. 92. 81. 70. 67. 75. 88. + 100. 106. 103. 94. 86. 76. 69. 65. 66. 63. 66. 88. 113. 110. 113. + 117. 118. 113. 103. 91. 84. 70. 65. 59. 58. 60. 59. 55. 50. 53. 58. + 63. 62. 80. 88. 85. 116. 146. 169. 174. 180. 169. 146. 132. 109. + 104. 119. 137. 152. 165. 175. 179. 177. 180. 183. 177. 187. 175. + 166. 167. 121. 68. 68. 60. 49. 46. 52. 55. 52. 41. 49. 59. 64. 63. + 59. 56. 55. 70. 85. 33. 53. 56. 56. 79. 95. 45. 45. 44. 80. 103. 88. + 127. 92. 41. 24. 66. 110. 112. 71. 29. 45. 74. 76. 116. 51. 64. 110. + 110. 117. 78. 91. 101. 49. 38. 41. 55. 49. 38. 39. 42. 46. 52. 61. + 71. 77. 82. 90. 100. 106. 107. 109. 114. 118. 119. 122. 125. 126. + 126. 126. 127. 129. 132. 130. 128. 126. 127. 129. 132. 134. 133. + 135. 136. 136. 135. 136. 138. 140. 142. 142. 142. 142. 142. 142. + 142. 142. 144. 144. 144. 145. 145. 146. 146. 146. 142. 144. 146. + 144. 141. 140. 141. 143. 145. 144. 144. 145. 146. 147. 148. 149. + 153. 153. 154. 156. 158. 161. 163. 165. 169. 171. 175. 178. 180. + 183. 187. 190. 190. 194. 198. 202. 204. 207. 210. 212. 209. 215. + 206. 215. 212. 170. 70. 74. 81. 90. 96. 96. 99. 106. 109. 107. 112. + 110. 110. 113. 117. 119. 116. 113. 117. 112. 106. 105. 105. 102. 95. + 89. 96. 100. 103. 101. 94. 86. 80. 77. 82. 88. 97. 101. 99. 92. 84. + 79. 76. 76. 74. 69. 70. 80. 99. 115. 111. 118. 121. 114. 106. 98. + 86. 73. 66. 64. 62. 60. 59. 57. 54. 51. 52. 56. 61. 58. 72. 78. 78. + 113. 147. 180. 189. 190. 182. 167. 148. 110. 105. 120. 139. 153. + 166. 176. 180. 178. 179. 183. 180. 191. 179. 159. 140. 85. 58. 64. + 66. 56. 45. 43. 49. 55. 42. 48. 56. 61. 60. 58. 58. 59. 68. 89. 57. + 47. 47. 51. 86. 77. 48. 45. 42. 85. 106. 75. 119. 115. 56. 53. 42. + 98. 122. 86. 65. 27. 54. 96. 102. 82. 44. 75. 96. 121. 106. 75. 66. + 53. 48. 41. 43. 41. 43. 45. 47. 50. 57. 67. 78. 86. 93. 100. 108. + 112. 112. 113. 116. 120. 120. 122. 125. 126. 126. 126. 127. 129. + 131. 130. 129. 128. 128. 130. 132. 133. 133. 134. 136. 136. 135. + 136. 138. 140. 141. 141. 141. 141. 141. 141. 141. 140. 144. 144. + 144. 145. 145. 146. 146. 146. 143. 145. 146. 145. 142. 141. 142. + 144. 145. 145. 145. 145. 146. 147. 148. 149. 152. 153. 154. 156. + 159. 162. 164. 166. 168. 171. 175. 178. 180. 183. 186. 189. 189. + 192. 197. 200. 202. 205. 208. 210. 207. 213. 205. 213. 214. 180. 84. + 72. 83. 91. 97. 98. 102. 110. 115. 114. 112. 113. 115. 118. 120. + 119. 116. 113. 119. 114. 109. 106. 105. 102. 97. 93. 103. 105. 107. + 102. 94. 86. 82. 82. 85. 92. 98. 97. 88. 79. 74. 73. 73. 74. 73. 73. + 77. 88. 105. 117. 119. 119. 114. 107. 102. 96. 82. 68. 61. 61. 60. + 58. 56. 53. 51. 49. 51. 55. 59. 52. 62. 67. 70. 111. 151. 191. 202. + 201. 197. 189. 165. 115. 106. 121. 140. 154. 167. 177. 181. 179. + 181. 182. 181. 190. 182. 159. 126. 72. 58. 59. 60. 58. 51. 44. 45. + 50. 47. 52. 56. 58. 56. 56. 59. 62. 51. 78. 79. 39. 42. 56. 114. 77. + 49. 47. 41. 91. 112. 60. 106. 135. 89. 60. 29. 78. 117. 97. 73. 31. + 23. 87. 88. 109. 61. 42. 77. 93. 116. 69. 47. 60. 45. 40. 43. 45. + 48. 50. 53. 58. 65. 76. 88. 96. 103. 109. 114. 117. 116. 115. 117. + 119. 121. 123. 125. 126. 126. 126. 127. 129. 129. 129. 129. 130. + 130. 131. 131. 131. 133. 134. 136. 136. 135. 135. 137. 139. 139. + 139. 139. 139. 139. 139. 140. 140. 144. 144. 144. 145. 145. 146. + 146. 146. 145. 146. 147. 146. 144. 143. 144. 146. 146. 145. 145. + 146. 146. 148. 149. 150. 152. 152. 154. 156. 159. 162. 165. 167. + 167. 170. 174. 177. 179. 182. 185. 188. 187. 191. 195. 198. 200. + 203. 206. 208. 204. 212. 206. 210. 216. 194. 107. 70. 81. 88. 93. + 96. 100. 106. 111. 111. 112. 116. 120. 122. 121. 118. 116. 115. 118. + 116. 112. 108. 105. 103. 102. 101. 113. 114. 112. 104. 94. 87. 87. + 90. 92. 98. 100. 92. 79. 69. 67. 70. 70. 71. 73. 79. 89. 101. 113. + 120. 127. 119. 107. 98. 94. 89. 75. 61. 56. 58. 59. 58. 54. 52. 53. + 55. 51. 54. 57. 49. 56. 59. 67. 113. 163. 195. 202. 205. 206. 198. + 175. 128. 106. 121. 140. 154. 166. 176. 180. 178. 183. 182. 179. + 184. 182. 166. 135. 97. 70. 54. 45. 50. 58. 56. 47. 41. 55. 57. 59. + 57. 55. 56. 61. 65. 46. 62. 88. 40. 45. 64. 135. 85. 46. 51. 45. 95. + 118. 54. 92. 129. 127. 48. 38. 55. 91. 99. 53. 60. 30. 63. 79. 100. + 95. 38. 74. 70. 110. 91. 71. 80. 38. 36. 44. 44. 47. 51. 58. 66. 76. + 86. 97. 103. 108. 111. 115. 117. 116. 116. 116. 118. 121. 124. 126. + 127. 126. 126. 127. 129. 128. 129. 130. 131. 132. 131. 130. 130. + 132. 134. 136. 136. 135. 135. 136. 137. 139. 139. 139. 139. 140. + 140. 140. 140. 144. 144. 144. 145. 145. 146. 146. 146. 147. 147. + 147. 147. 146. 146. 146. 147. 146. 146. 146. 146. 147. 148. 150. + 150. 151. 152. 154. 156. 160. 163. 166. 168. 166. 169. 173. 176. + 178. 181. 184. 187. 187. 191. 195. 198. 200. 202. 205. 207. 205. + 213. 208. 207. 217. 205. 133. 70. 79. 84. 91. 95. 98. 101. 103. 104. + 113. 117. 122. 122. 119. 117. 117. 118. 115. 115. 113. 110. 107. + 107. 109. 112. 121. 120. 115. 105. 95. 91. 94. 99. 98. 99. 97. 88. + 78. 71. 72. 74. 69. 71. 77. 88. 102. 114. 121. 123. 128. 118. 105. + 94. 87. 78. 66. 55. 53. 57. 59. 58. 55. 57. 64. 71. 50. 52. 56. 49. + 55. 57. 66. 116. 178. 195. 196. 206. 208. 196. 179. 146. 106. 121. + 139. 153. 165. 174. 178. 176. 181. 181. 181. 179. 179. 167. 136. + 116. 74. 56. 42. 45. 56. 58. 51. 43. 57. 59. 60. 59. 58. 61. 67. 73. + 62. 57. 83. 51. 50. 68. 124. 77. 44. 55. 51. 97. 120. 55. 81. 103. + 146. 69. 49. 35. 69. 105. 66. 69. 64. 57. 72. 82. 91. 55. 69. 78. + 104. 108. 96. 112. 63. 39. 37. 32. 45. 52. 63. 74. 84. 93. 101. 105. + 109. 111. 114. 117. 117. 118. 119. 120. 122. 125. 127. 127. 127. + 126. 127. 128. 127. 128. 130. 132. 132. 131. 130. 129. 132. 134. + 136. 137. 135. 134. 135. 136. 139. 139. 140. 140. 141. 141. 142. + 142. 144. 144. 144. 145. 145. 146. 146. 146. 148. 147. 147. 147. + 148. 148. 148. 147. 147. 147. 147. 147. 148. 149. 151. 151. 152. + 153. 155. 157. 160. 163. 166. 168. 165. 168. 171. 174. 176. 179. + 183. 186. 188. 191. 195. 198. 200. 202. 204. 206. 207. 213. 212. + 206. 216. 211. 159. 77. 78. 83. 91. 98. 102. 102. 103. 105. 113. + 117. 120. 120. 117. 116. 119. 122. 112. 113. 113. 112. 112. 114. + 118. 122. 126. 122. 113. 104. 96. 94. 98. 101. 96. 92. 88. 84. 82. + 81. 80. 79. 72. 75. 84. 99. 114. 124. 126. 125. 121. 114. 103. 91. + 78. 66. 57. 52. 51. 54. 57. 57. 59. 66. 78. 88. 49. 50. 54. 50. 57. + 56. 63. 112. 184. 196. 193. 204. 207. 193. 181. 156. 106. 120. 138. + 152. 164. 174. 177. 175. 178. 179. 185. 179. 179. 161. 118. 106. 65. + 62. 53. 45. 45. 50. 53. 51. 53. 56. 60. 61. 62. 67. 74. 80. 72. 53. + 65. 66. 59. 86. 106. 67. 49. 56. 54. 99. 116. 54. 76. 79. 129. 112. + 64. 31. 65. 119. 107. 50. 61. 54. 67. 87. 69. 70. 44. 70. 86. 94. + 84. 122. 109. 62. 45. 36. 52. 59. 70. 81. 90. 97. 102. 106. 111. + 113. 115. 118. 120. 122. 124. 124. 123. 125. 128. 128. 127. 126. + 127. 128. 127. 128. 130. 131. 132. 131. 130. 129. 131. 134. 136. + 137. 135. 134. 134. 134. 139. 139. 140. 140. 141. 142. 142. 142. + 144. 144. 144. 145. 145. 146. 146. 146. 148. 147. 146. 147. 149. + 149. 149. 147. 148. 148. 148. 148. 149. 150. 151. 152. 154. 155. + 156. 158. 160. 163. 165. 166. 164. 167. 170. 173. 175. 178. 182. + 185. 188. 191. 195. 198. 199. 201. 203. 205. 208. 211. 214. 207. + 214. 212. 183. 92. 78. 80. 86. 95. 98. 99. 102. 107. 111. 114. 117. + 119. 120. 121. 122. 124. 114. 114. 115. 117. 120. 124. 127. 129. + 127. 119. 108. 99. 95. 94. 94. 94. 86. 82. 80. 82. 86. 87. 85. 81. + 77. 83. 94. 109. 122. 129. 128. 126. 113. 105. 94. 83. 69. 56. 50. + 50. 48. 51. 56. 61. 67. 77. 90. 99. 49. 47. 51. 49. 57. 53. 56. 103. + 175. 196. 196. 200. 201. 193. 182. 150. 107. 122. 140. 153. 165. + 174. 177. 176. 179. 179. 185. 178. 183. 161. 104. 92. 59. 63. 55. + 41. 40. 51. 55. 48. 53. 57. 62. 64. 65. 67. 73. 77. 73. 55. 47. 82. + 72. 120. 95. 59. 62. 53. 53. 103. 110. 47. 74. 72. 92. 119. 99. 45. + 65. 130. 113. 41. 42. 46. 63. 84. 69. 71. 39. 49. 62. 83. 65. 91. + 122. 83. 72. 53. 68. 72. 79. 86. 92. 97. 103. 107. 113. 113. 115. + 118. 121. 124. 125. 125. 124. 126. 128. 128. 127. 126. 127. 128. + 128. 129. 130. 130. 131. 131. 131. 130. 131. 134. 137. 137. 135. + 134. 133. 133. 137. 137. 138. 139. 140. 141. 141. 142. 144. 144. + 144. 145. 145. 146. 146. 146. 148. 146. 145. 146. 149. 150. 149. + 147. 148. 148. 148. 149. 149. 151. 152. 153. 156. 157. 157. 158. + 160. 162. 164. 165. 163. 166. 169. 172. 174. 177. 181. 184. 186. + 190. 193. 196. 197. 199. 201. 203. 207. 206. 214. 208. 212. 211. + 204. 111. 88. 85. 85. 89. 91. 91. 97. 106. 107. 110. 116. 123. 128. + 129. 126. 124. 121. 120. 120. 123. 129. 133. 133. 132. 126. 115. + 101. 93. 91. 89. 84. 78. 76. 77. 81. 85. 89. 88. 85. 82. 84. 91. + 104. 117. 127. 130. 128. 125. 110. 95. 79. 69. 60. 50. 46. 47. 48. + 53. 61. 70. 81. 90. 98. 102. 48. 45. 48. 48. 56. 49. 49. 95. 162. + 195. 199. 195. 194. 194. 180. 139. 108. 123. 141. 155. 166. 176. + 178. 177. 185. 179. 183. 176. 186. 167. 104. 92. 61. 61. 48. 33. 42. + 62. 57. 35. 57. 61. 65. 66. 64. 64. 67. 69. 79. 67. 44. 96. 82. 143. + 87. 46. 73. 49. 51. 107. 105. 38. 74. 77. 63. 91. 137. 63. 62. 133. + 83. 51. 49. 45. 60. 59. 81. 65. 64. 48. 52. 96. 65. 52. 101. 87. 90. + 59. 81. 83. 86. 89. 92. 97. 104. 108. 113. 113. 114. 116. 120. 122. + 123. 123. 124. 126. 128. 129. 127. 126. 127. 128. 129. 129. 129. + 130. 130. 131. 131. 131. 131. 134. 137. 137. 136. 133. 132. 132. + 135. 136. 137. 137. 138. 139. 140. 140. 144. 144. 144. 145. 145. + 146. 146. 146. 148. 145. 144. 145. 149. 150. 149. 146. 149. 149. + 149. 149. 150. 151. 152. 153. 158. 158. 158. 159. 160. 162. 163. + 164. 162. 165. 169. 172. 174. 177. 181. 183. 185. 188. 192. 194. + 195. 197. 199. 201. 205. 202. 213. 209. 210. 210. 215. 124. 107. 99. + 92. 91. 89. 89. 97. 108. 104. 108. 116. 127. 135. 135. 129. 123. + 128. 125. 124. 128. 135. 138. 136. 132. 126. 112. 96. 89. 88. 85. + 75. 66. 71. 78. 86. 91. 91. 88. 85. 84. 88. 97. 110. 122. 128. 129. + 127. 125. 110. 88. 67. 58. 53. 47. 44. 44. 51. 57. 67. 81. 93. 101. + 104. 104.
+ + 1 + 1 +
d
+ + 0.
+ + 65536 + 1 +
d
+ + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0.
+ + <_ type_id="opencv-matrix"> + 1 + 1 +
d
+ + 0.
+ + 1 + 1 +
i
+ + 1
+
diff --git a/test/fisherfaces_save.xml b/test/fisherfaces_save.xml new file mode 100644 index 00000000..a0e2daec --- /dev/null +++ b/test/fisherfaces_save.xml @@ -0,0 +1,7530 @@ + + +1 + + 1 + 65536 +
d
+ + 162. 162. 162. 163. 164. 162. 158. 155. 158. 157. 156. 156. 155. + 155. 156. 156. 158. 159. 161. 164. 167. 169. 171. 172. 170. 170. + 167. 160. 152. 142. 127. 112. 98. 94. 95. 101. 105. 105. 105. 108. + 109. 109. 108. 107. 107. 108. 108. 109. 111. 107. 105. 108. 110. + 111. 115. 121. 118. 121. 124. 126. 126. 127. 128. 130. 133. 131. + 129. 130. 132. 133. 131. 129. 127. 129. 130. 129. 129. 130. 132. + 134. 133. 133. 133. 134. 134. 135. 135. 135. 134. 133. 132. 132. + 134. 134. 133. 132. 135. 136. 136. 136. 136. 135. 134. 133. 138. + 136. 133. 131. 130. 131. 132. 134. 131. 132. 133. 133. 131. 131. + 132. 133. 135. 135. 135. 134. 134. 134. 133. 133. 142. 136. 130. + 129. 132. 134. 132. 129. 129. 130. 132. 131. 129. 129. 130. 131. + 130. 130. 130. 129. 128. 127. 126. 125. 124. 124. 124. 121. 118. + 113. 108. 105. 109. 116. 127. 135. 141. 146. 151. 155. 161. 160. + 158. 154. 151. 150. 152. 154. 154. 155. 155. 156. 156. 155. 155. + 154. 152. 152. 152. 153. 153. 154. 154. 154. 156. 155. 155. 157. + 158. 158. 156. 153. 148. 170. 192. 203. 211. 220. 219. 212. 215. + 210. 180. 133. 104. 105. 110. 109. 116. 117. 119. 120. 121. 120. + 119. 119. 122. 123. 123. 122. 120. 120. 122. 124. 122. 123. 125. + 126. 125. 123. 121. 119. 126. 126. 126. 126. 126. 126. 126. 126. + 120. 121. 117. 121. 146. 172. 164. 138. 162. 161. 161. 162. 163. + 161. 158. 155. 157. 157. 156. 155. 154. 155. 155. 155. 156. 158. + 160. 163. 166. 169. 171. 172. 171. 171. 167. 159. 151. 141. 126. + 111. 97. 93. 94. 99. 103. 104. 104. 107. 107. 107. 107. 107. 107. + 107. 108. 108. 110. 106. 105. 108. 110. 111. 115. 120. 119. 122. + 124. 126. 126. 126. 127. 129. 133. 131. 129. 130. 132. 133. 131. + 129. 127. 129. 130. 130. 129. 130. 132. 134. 133. 133. 133. 134. + 134. 134. 135. 135. 134. 133. 131. 132. 134. 134. 133. 132. 134. + 135. 135. 135. 135. 134. 133. 132. 137. 135. 133. 131. 130. 130. + 131. 132. 131. 132. 133. 133. 131. 130. 132. 133. 134. 134. 134. + 134. 133. 133. 132. 132. 141. 135. 130. 129. 131. 133. 131. 128. + 128. 130. 131. 130. 129. 128. 129. 131. 129. 130. 130. 129. 128. + 127. 126. 125. 124. 124. 123. 121. 117. 112. 108. 105. 109. 116. + 127. 136. 142. 148. 153. 156. 161. 161. 159. 155. 151. 150. 151. + 153. 153. 154. 155. 155. 155. 155. 154. 153. 152. 152. 152. 153. + 153. 154. 154. 154. 156. 155. 155. 156. 158. 158. 155. 153. 151. + 171. 195. 208. 213. 216. 218. 217. 216. 207. 177. 135. 105. 100. + 105. 108. 116. 117. 119. 120. 121. 121. 120. 119. 122. 122. 123. + 122. 120. 120. 122. 124. 122. 123. 125. 125. 125. 123. 121. 120. + 126. 126. 126. 126. 126. 125. 125. 125. 113. 115. 115. 124. 153. + 179. 173. 150. 160. 159. 159. 160. 161. 160. 157. 154. 156. 156. + 155. 154. 154. 154. 154. 154. 154. 156. 159. 163. 166. 169. 171. + 172. 172. 171. 167. 158. 150. 140. 124. 110. 96. 92. 92. 97. 102. + 102. 103. 106. 105. 105. 105. 106. 106. 107. 107. 108. 109. 106. + 105. 108. 111. 111. 115. 120. 120. 122. 125. 126. 125. 125. 126. + 127. 132. 130. 129. 130. 131. 132. 131. 130. 128. 129. 130. 130. + 129. 129. 132. 134. 133. 133. 133. 133. 134. 134. 134. 135. 134. + 132. 131. 132. 133. 134. 133. 131. 133. 133. 134. 134. 133. 132. + 131. 131. 135. 134. 132. 130. 129. 129. 130. 131. 130. 132. 133. + 132. 131. 130. 131. 133. 133. 133. 133. 132. 132. 132. 131. 131. + 138. 134. 129. 128. 130. 132. 130. 128. 127. 128. 130. 129. 127. + 127. 128. 129. 129. 129. 129. 129. 128. 127. 126. 125. 123. 123. + 122. 119. 116. 111. 107. 105. 107. 114. 125. 135. 143. 149. 154. + 157. 160. 160. 159. 156. 153. 151. 151. 152. 152. 153. 154. 154. + 154. 154. 153. 152. 153. 153. 153. 153. 154. 154. 154. 154. 155. + 155. 154. 155. 157. 157. 155. 153. 151. 167. 191. 209. 213. 211. + 214. 220. 219. 207. 182. 146. 112. 96. 100. 110. 115. 116. 119. 120. + 121. 121. 121. 120. 121. 122. 123. 122. 120. 120. 122. 124. 122. + 123. 124. 125. 125. 123. 122. 120. 125. 125. 125. 125. 125. 125. + 125. 125. 117. 121. 123. 128. 144. 155. 140. 116. 159. 158. 157. + 158. 159. 158. 156. 154. 156. 155. 154. 153. 153. 153. 153. 154. + 153. 155. 159. 163. 167. 169. 171. 171. 172. 171. 166. 157. 148. + 138. 122. 108. 95. 91. 90. 95. 100. 100. 102. 105. 103. 103. 104. + 105. 106. 106. 106. 106. 108. 104. 105. 109. 111. 111. 115. 120. + 121. 123. 125. 126. 125. 124. 125. 126. 130. 129. 129. 130. 131. + 131. 131. 131. 128. 129. 130. 130. 129. 129. 131. 133. 132. 132. + 133. 133. 133. 134. 134. 134. 133. 132. 131. 131. 133. 134. 132. + 131. 132. 132. 132. 132. 132. 131. 130. 129. 133. 132. 131. 129. + 129. 128. 129. 129. 130. 131. 133. 132. 130. 130. 131. 132. 132. + 132. 132. 131. 131. 130. 130. 130. 135. 132. 129. 128. 130. 130. + 129. 127. 126. 127. 128. 128. 126. 126. 127. 128. 129. 129. 129. + 129. 129. 128. 127. 126. 123. 122. 121. 119. 115. 111. 108. 106. + 105. 111. 120. 131. 140. 147. 152. 155. 159. 160. 160. 158. 154. + 152. 152. 152. 152. 153. 153. 154. 154. 153. 153. 152. 153. 154. + 154. 154. 154. 154. 154. 154. 155. 154. 153. 154. 156. 156. 155. + 153. 151. 157. 176. 200. 210. 209. 211. 219. 219. 212. 197. 169. + 129. 99. 97. 111. 114. 115. 117. 120. 121. 121. 121. 121. 121. 122. + 122. 121. 120. 119. 121. 123. 122. 123. 124. 124. 124. 123. 122. + 122. 124. 124. 124. 125. 125. 125. 125. 125. 123. 128. 129. 123. + 115. 102. 80. 58. 158. 157. 156. 156. 158. 158. 156. 154. 156. 155. + 154. 153. 153. 153. 153. 154. 154. 156. 160. 164. 168. 170. 171. + 171. 172. 170. 164. 155. 146. 136. 121. 107. 95. 90. 89. 94. 98. 99. + 101. 105. 102. 103. 104. 106. 106. 106. 105. 105. 106. 103. 104. + 109. 111. 111. 114. 119. 120. 122. 125. 125. 124. 124. 124. 126. + 128. 129. 129. 130. 130. 130. 131. 132. 129. 130. 131. 130. 129. + 129. 131. 133. 132. 132. 132. 133. 133. 133. 134. 134. 133. 132. + 130. 131. 133. 133. 132. 131. 131. 131. 131. 131. 131. 130. 129. + 129. 132. 132. 131. 130. 129. 128. 128. 128. 130. 131. 132. 132. + 130. 129. 131. 132. 132. 132. 131. 131. 130. 130. 130. 130. 133. + 131. 130. 129. 129. 129. 129. 128. 125. 127. 128. 127. 126. 125. + 126. 128. 128. 128. 129. 129. 129. 128. 127. 126. 124. 123. 121. + 118. 115. 112. 109. 108. 103. 107. 114. 123. 134. 142. 148. 151. + 156. 158. 160. 159. 156. 154. 153. 153. 154. 154. 155. 155. 155. + 155. 154. 154. 155. 154. 154. 154. 154. 154. 154. 154. 155. 153. + 152. 152. 154. 155. 154. 153. 153. 150. 160. 185. 205. 211. 213. + 217. 216. 216. 213. 193. 150. 109. 98. 108. 111. 113. 116. 118. 120. + 121. 121. 121. 120. 121. 122. 121. 119. 119. 121. 123. 122. 123. + 123. 123. 124. 123. 123. 123. 124. 124. 124. 125. 125. 126. 126. + 126. 127. 127. 120. 103. 80. 61. 47. 40. 158. 156. 155. 156. 157. + 158. 156. 155. 156. 156. 155. 154. 154. 154. 154. 154. 155. 158. + 162. 166. 169. 170. 170. 170. 170. 169. 162. 153. 144. 135. 121. + 108. 95. 90. 89. 93. 97. 99. 101. 105. 103. 104. 106. 107. 107. 106. + 104. 103. 105. 102. 104. 109. 112. 112. 114. 119. 119. 121. 124. + 125. 124. 124. 125. 126. 126. 128. 130. 130. 129. 129. 131. 132. + 129. 130. 131. 130. 128. 128. 130. 132. 131. 132. 132. 132. 133. + 133. 133. 133. 133. 131. 130. 131. 132. 133. 132. 130. 131. 131. + 131. 131. 131. 130. 129. 128. 132. 132. 131. 130. 130. 129. 128. + 128. 129. 131. 132. 131. 130. 129. 130. 132. 132. 132. 132. 131. + 131. 130. 130. 130. 131. 131. 131. 130. 130. 129. 129. 129. 126. + 127. 128. 128. 126. 126. 127. 128. 127. 128. 128. 129. 129. 128. + 127. 127. 125. 124. 121. 119. 116. 113. 111. 110. 103. 104. 108. + 116. 127. 137. 145. 148. 153. 156. 159. 160. 158. 156. 155. 155. + 156. 156. 157. 158. 158. 157. 156. 156. 155. 155. 155. 155. 154. + 154. 154. 154. 155. 153. 151. 151. 153. 154. 153. 153. 157. 149. + 151. 170. 195. 211. 215. 215. 212. 217. 221. 208. 172. 130. 107. + 104. 108. 110. 113. 116. 119. 120. 120. 120. 120. 121. 121. 120. + 119. 119. 120. 122. 122. 122. 122. 123. 123. 123. 124. 124. 124. + 125. 125. 126. 126. 127. 128. 128. 133. 122. 102. 79. 56. 42. 43. + 50. 158. 157. 155. 155. 157. 158. 157. 156. 157. 157. 156. 155. 154. + 155. 155. 155. 158. 161. 165. 168. 170. 171. 170. 169. 168. 167. + 160. 151. 143. 135. 121. 109. 96. 91. 89. 93. 97. 99. 102. 106. 105. + 106. 108. 108. 107. 105. 103. 102. 103. 101. 103. 109. 112. 112. + 114. 118. 117. 120. 123. 124. 124. 124. 126. 127. 125. 128. 130. + 130. 128. 128. 131. 133. 130. 131. 131. 130. 128. 128. 130. 132. + 131. 131. 132. 132. 132. 133. 133. 133. 132. 131. 130. 130. 132. + 133. 131. 130. 131. 131. 132. 132. 131. 130. 129. 129. 132. 132. + 132. 132. 131. 130. 129. 128. 129. 130. 132. 131. 129. 129. 130. + 131. 133. 132. 132. 132. 131. 131. 131. 131. 130. 131. 132. 132. + 131. 130. 130. 130. 126. 128. 129. 128. 127. 126. 127. 129. 127. + 128. 128. 129. 129. 128. 128. 127. 126. 125. 122. 119. 116. 114. + 113. 112. 105. 104. 105. 111. 122. 134. 142. 146. 150. 154. 158. + 161. 160. 158. 157. 157. 159. 159. 160. 160. 160. 160. 159. 159. + 156. 156. 156. 155. 155. 154. 154. 154. 155. 153. 150. 150. 152. + 153. 153. 152. 157. 151. 148. 157. 180. 203. 213. 212. 215. 217. + 220. 215. 194. 160. 125. 103. 106. 108. 111. 114. 117. 118. 119. + 119. 120. 121. 121. 120. 119. 118. 120. 122. 122. 122. 122. 122. + 123. 123. 124. 125. 125. 125. 126. 127. 128. 129. 129. 130. 122. + 101. 77. 60. 48. 41. 45. 54. 159. 157. 155. 155. 157. 158. 158. 157. + 158. 157. 156. 156. 155. 155. 156. 156. 160. 162. 166. 170. 171. + 171. 169. 168. 167. 166. 159. 150. 143. 135. 122. 109. 97. 91. 89. + 93. 97. 99. 102. 107. 107. 108. 109. 109. 108. 105. 103. 101. 103. + 101. 103. 109. 112. 112. 114. 118. 116. 119. 122. 124. 124. 125. + 126. 128. 124. 127. 130. 130. 128. 128. 131. 133. 130. 131. 131. + 130. 128. 128. 130. 132. 131. 131. 131. 132. 132. 133. 133. 133. + 132. 131. 130. 130. 132. 132. 131. 130. 131. 132. 132. 132. 132. + 131. 130. 129. 132. 133. 133. 132. 131. 130. 129. 128. 129. 130. + 131. 131. 129. 129. 130. 131. 133. 133. 133. 132. 132. 132. 131. + 131. 130. 132. 133. 133. 131. 130. 130. 131. 127. 128. 129. 129. + 127. 127. 128. 129. 127. 127. 128. 129. 129. 129. 128. 128. 127. + 125. 123. 120. 117. 115. 114. 113. 108. 105. 103. 109. 120. 132. + 142. 146. 148. 152. 158. 161. 161. 159. 158. 158. 161. 161. 162. + 162. 162. 162. 161. 161. 156. 156. 156. 155. 155. 154. 154. 154. + 155. 152. 150. 150. 151. 153. 153. 152. 154. 152. 147. 147. 166. + 194. 208. 208. 221. 219. 218. 217. 210. 184. 141. 106. 104. 106. + 109. 113. 116. 117. 118. 118. 120. 121. 121. 120. 118. 118. 120. + 122. 122. 122. 122. 122. 123. 123. 125. 125. 126. 126. 127. 128. + 129. 130. 130. 131. 94. 71. 52. 49. 50. 48. 48. 51. 158. 158. 157. + 157. 157. 157. 157. 157. 155. 159. 161. 159. 154. 152. 156. 160. + 164. 165. 167. 169. 168. 167. 165. 163. 164. 163. 157. 149. 142. + 134. 120. 107. 96. 90. 87. 92. 97. 98. 99. 101. 107. 107. 107. 106. + 106. 106. 105. 105. 101. 102. 103. 106. 109. 112. 115. 116. 119. + 119. 120. 121. 123. 124. 125. 125. 129. 128. 127. 126. 127. 130. + 132. 134. 130. 131. 131. 132. 132. 131. 131. 130. 133. 132. 132. + 131. 131. 132. 132. 133. 136. 136. 135. 134. 133. 133. 133. 134. + 132. 133. 134. 133. 131. 130. 131. 132. 133. 132. 132. 132. 132. + 132. 132. 132. 130. 132. 133. 132. 129. 128. 131. 134. 132. 133. + 133. 134. 133. 132. 130. 129. 132. 132. 133. 132. 131. 130. 129. + 128. 129. 129. 129. 128. 128. 127. 127. 127. 131. 130. 130. 129. + 129. 128. 128. 128. 128. 125. 122. 120. 119. 117. 115. 113. 110. + 108. 106. 106. 111. 122. 136. 146. 146. 150. 155. 159. 160. 160. + 161. 163. 158. 159. 161. 162. 163. 163. 162. 161. 156. 157. 160. + 161. 160. 157. 154. 152. 155. 154. 153. 152. 152. 152. 153. 153. + 151. 151. 146. 144. 154. 176. 197. 207. 214. 217. 217. 217. 217. + 203. 167. 132. 104. 104. 106. 111. 115. 116. 116. 116. 121. 122. + 123. 124. 123. 122. 121. 120. 125. 124. 122. 122. 122. 124. 126. + 127. 127. 131. 132. 131. 133. 131. 117. 98. 56. 51. 45. 44. 45. 47. + 45. 42. 156. 156. 156. 157. 157. 157. 157. 157. 156. 159. 160. 157. + 153. 152. 157. 161. 164. 165. 167. 168. 168. 166. 164. 163. 162. + 161. 157. 150. 144. 137. 124. 111. 97. 91. 88. 93. 98. 99. 100. 103. + 107. 106. 106. 106. 105. 105. 105. 104. 101. 102. 103. 106. 109. + 112. 115. 116. 119. 119. 120. 121. 123. 124. 125. 125. 126. 127. + 128. 129. 130. 130. 131. 131. 130. 131. 131. 132. 132. 131. 131. + 130. 133. 132. 132. 131. 131. 132. 132. 133. 134. 133. 132. 132. + 131. 131. 131. 132. 130. 131. 133. 133. 131. 131. 132. 134. 132. + 132. 132. 132. 131. 131. 131. 131. 130. 131. 132. 131. 129. 128. + 131. 133. 132. 133. 135. 136. 135. 133. 131. 129. 132. 132. 132. + 132. 131. 130. 129. 128. 129. 129. 128. 128. 128. 127. 127. 127. + 130. 129. 129. 129. 128. 128. 127. 127. 127. 125. 122. 121. 120. + 118. 115. 112. 110. 108. 106. 106. 110. 121. 134. 144. 147. 151. + 156. 159. 160. 161. 162. 163. 158. 159. 161. 162. 162. 162. 161. + 161. 157. 158. 159. 159. 159. 157. 154. 153. 154. 154. 153. 152. + 152. 152. 152. 152. 149. 150. 150. 148. 150. 164. 187. 205. 212. + 216. 217. 218. 221. 212. 183. 153. 108. 104. 105. 111. 114. 112. + 113. 117. 120. 121. 123. 124. 125. 124. 123. 123. 123. 123. 124. + 125. 126. 127. 127. 127. 135. 130. 130. 136. 138. 122. 92. 67. 49. + 49. 48. 46. 46. 47. 50. 52. 154. 155. 155. 156. 156. 157. 157. 158. + 157. 158. 158. 155. 152. 153. 158. 163. 165. 166. 167. 167. 167. + 165. 163. 162. 160. 160. 157. 151. 146. 139. 127. 114. 98. 91. 88. + 93. 99. 100. 101. 104. 106. 105. 105. 105. 104. 104. 104. 103. 102. + 102. 104. 106. 109. 112. 114. 116. 119. 119. 120. 121. 123. 124. + 125. 125. 124. 126. 129. 131. 131. 131. 129. 128. 130. 130. 131. + 131. 131. 131. 130. 130. 132. 132. 131. 131. 131. 131. 132. 132. + 132. 131. 130. 129. 129. 129. 130. 130. 129. 130. 132. 132. 131. + 131. 133. 135. 130. 130. 130. 130. 130. 130. 131. 131. 129. 130. + 131. 130. 128. 128. 130. 132. 131. 133. 135. 137. 136. 134. 131. + 129. 132. 132. 132. 132. 131. 130. 128. 128. 129. 128. 128. 128. + 127. 127. 127. 127. 128. 128. 128. 127. 127. 127. 126. 126. 126. + 124. 123. 122. 121. 118. 114. 111. 111. 109. 106. 105. 109. 119. + 131. 140. 147. 151. 156. 159. 161. 162. 163. 164. 159. 160. 160. + 161. 162. 161. 161. 161. 159. 159. 158. 158. 157. 156. 155. 155. + 154. 153. 152. 151. 151. 151. 151. 152. 149. 149. 152. 152. 147. + 150. 172. 198. 207. 212. 215. 217. 221. 220. 202. 180. 125. 111. + 104. 110. 114. 110. 112. 121. 117. 118. 120. 122. 124. 124. 124. + 123. 120. 122. 125. 128. 130. 130. 129. 128. 133. 132. 135. 139. + 127. 97. 64. 44. 45. 49. 51. 49. 46. 47. 52. 57. 153. 153. 154. 155. + 156. 157. 158. 158. 158. 158. 157. 154. 152. 155. 160. 165. 166. + 166. 166. 166. 165. 163. 162. 161. 159. 160. 157. 151. 146. 139. + 125. 113. 96. 90. 87. 92. 98. 100. 101. 103. 105. 105. 104. 104. + 104. 103. 103. 103. 102. 103. 104. 106. 108. 111. 114. 115. 119. + 119. 120. 121. 123. 124. 125. 125. 125. 126. 128. 129. 130. 130. + 129. 128. 129. 130. 131. 131. 131. 131. 130. 129. 132. 132. 131. + 130. 130. 131. 132. 132. 130. 130. 129. 129. 128. 129. 129. 130. + 130. 132. 133. 132. 130. 130. 131. 132. 128. 128. 128. 129. 129. + 129. 129. 130. 129. 129. 129. 128. 128. 128. 129. 130. 129. 131. + 134. 136. 136. 133. 130. 128. 131. 132. 132. 131. 131. 129. 128. + 127. 128. 128. 128. 127. 127. 127. 126. 126. 126. 126. 126. 126. + 126. 126. 126. 126. 125. 124. 123. 123. 122. 119. 114. 110. 111. + 109. 106. 105. 108. 117. 128. 136. 146. 150. 155. 159. 161. 162. + 163. 164. 160. 160. 160. 160. 161. 161. 160. 160. 160. 159. 158. + 156. 155. 155. 156. 156. 154. 153. 152. 151. 151. 151. 151. 151. + 152. 148. 151. 154. 147. 141. 158. 184. 201. 209. 213. 214. 218. + 222. 213. 199. 154. 125. 104. 107. 113. 112. 115. 124. 116. 117. + 119. 121. 121. 121. 121. 120. 120. 121. 124. 127. 129. 130. 131. + 131. 127. 138. 142. 125. 95. 68. 52. 44. 48. 49. 50. 49. 47. 48. 51. + 54. 153. 154. 155. 156. 157. 158. 158. 159. 159. 158. 156. 154. 154. + 157. 162. 166. 167. 167. 166. 165. 163. 162. 160. 159. 160. 161. + 157. 151. 145. 136. 121. 108. 94. 88. 85. 90. 96. 98. 100. 102. 105. + 105. 104. 104. 104. 103. 103. 103. 103. 103. 104. 106. 108. 111. + 113. 115. 119. 119. 120. 121. 123. 124. 125. 125. 128. 128. 127. + 126. 126. 128. 129. 130. 129. 129. 130. 131. 131. 130. 129. 129. + 132. 131. 130. 130. 130. 130. 131. 132. 131. 130. 130. 129. 130. + 130. 131. 131. 134. 134. 134. 132. 129. 127. 127. 128. 126. 126. + 126. 127. 127. 128. 128. 129. 129. 128. 127. 126. 127. 128. 128. + 128. 127. 128. 131. 133. 133. 131. 129. 127. 131. 131. 131. 131. + 130. 129. 128. 127. 128. 128. 127. 127. 127. 126. 126. 126. 125. + 125. 125. 126. 126. 126. 126. 126. 125. 124. 123. 123. 122. 119. + 114. 110. 111. 109. 107. 106. 108. 116. 126. 134. 144. 149. 154. + 158. 160. 161. 163. 164. 160. 160. 160. 160. 159. 159. 160. 160. + 161. 160. 157. 155. 155. 155. 156. 157. 154. 153. 152. 151. 151. + 151. 152. 152. 156. 148. 147. 152. 148. 141. 149. 167. 195. 207. + 214. 214. 216. 221. 218. 210. 184. 144. 108. 101. 109. 112. 115. + 121. 119. 120. 121. 122. 122. 121. 120. 119. 121. 121. 122. 123. + 125. 128. 131. 133. 132. 140. 127. 90. 61. 54. 52. 47. 48. 46. 45. + 46. 50. 52. 51. 50. 155. 156. 156. 157. 157. 158. 159. 159. 160. + 158. 157. 156. 158. 161. 165. 167. 168. 167. 165. 164. 162. 160. + 159. 158. 161. 162. 158. 151. 144. 134. 118. 104. 92. 86. 84. 89. + 95. 97. 99. 102. 106. 105. 105. 105. 104. 104. 104. 103. 103. 104. + 105. 106. 108. 111. 113. 114. 119. 119. 120. 121. 123. 124. 125. + 125. 130. 128. 126. 125. 125. 126. 129. 130. 129. 129. 130. 130. + 130. 130. 129. 129. 131. 131. 130. 130. 130. 130. 131. 131. 131. + 131. 130. 130. 131. 131. 132. 133. 135. 136. 135. 132. 128. 126. + 125. 126. 124. 124. 125. 125. 126. 127. 127. 128. 128. 126. 125. + 125. 126. 127. 127. 126. 126. 127. 129. 130. 130. 130. 129. 128. + 131. 131. 131. 131. 130. 129. 127. 127. 127. 127. 127. 127. 126. + 126. 126. 125. 125. 125. 125. 126. 126. 126. 127. 127. 126. 124. + 123. 122. 121. 118. 114. 111. 111. 110. 108. 106. 109. 116. 126. + 134. 143. 147. 153. 157. 159. 160. 162. 163. 161. 160. 160. 159. + 158. 159. 159. 159. 161. 159. 158. 156. 155. 155. 156. 157. 155. + 154. 153. 153. 152. 152. 153. 153. 157. 149. 147. 150. 149. 144. + 146. 153. 185. 202. 215. 216. 216. 221. 222. 217. 204. 166. 123. + 102. 103. 110. 114. 115. 122. 123. 124. 125. 124. 123. 121. 120. + 122. 122. 121. 122. 124. 128. 131. 134. 138. 122. 89. 56. 47. 54. + 53. 41. 45. 42. 41. 45. 52. 56. 54. 52. 158. 158. 158. 158. 158. + 159. 159. 159. 160. 159. 158. 159. 162. 165. 167. 168. 168. 167. + 165. 163. 161. 159. 158. 157. 162. 163. 160. 153. 145. 135. 119. + 105. 93. 87. 84. 90. 96. 98. 100. 103. 107. 106. 106. 106. 105. 105. + 105. 104. 104. 104. 105. 106. 108. 111. 113. 114. 119. 119. 120. + 121. 123. 124. 125. 125. 128. 127. 127. 127. 127. 127. 127. 127. + 128. 129. 129. 130. 130. 129. 129. 128. 131. 130. 130. 129. 129. + 130. 130. 131. 130. 130. 130. 130. 130. 131. 132. 133. 134. 135. + 134. 132. 128. 126. 126. 126. 122. 123. 123. 124. 125. 126. 126. + 127. 128. 125. 123. 123. 126. 127. 126. 124. 128. 128. 128. 128. + 129. 130. 130. 131. 130. 131. 131. 130. 130. 128. 127. 126. 127. + 127. 127. 126. 126. 126. 125. 125. 125. 126. 126. 126. 127. 127. + 128. 128. 127. 125. 122. 121. 120. 118. 115. 112. 111. 110. 108. + 107. 110. 117. 127. 134. 141. 145. 151. 155. 157. 159. 161. 162. + 162. 161. 159. 158. 158. 158. 159. 159. 160. 159. 158. 157. 156. + 156. 156. 156. 156. 156. 155. 154. 153. 153. 154. 154. 153. 152. + 151. 149. 148. 146. 146. 146. 168. 190. 210. 215. 215. 220. 223. + 221. 216. 190. 148. 114. 103. 108. 113. 113. 119. 120. 122. 123. + 123. 122. 121. 120. 122. 123. 124. 125. 127. 129. 131. 132. 122. 87. + 53. 43. 49. 50. 46. 42. 44. 44. 46. 49. 52. 54. 54. 54. 160. 160. + 160. 159. 159. 159. 159. 159. 160. 159. 159. 161. 164. 167. 168. + 168. 169. 167. 165. 162. 160. 158. 157. 157. 162. 163. 160. 154. + 147. 137. 121. 107. 94. 87. 85. 91. 97. 100. 102. 104. 107. 107. + 107. 106. 106. 106. 105. 105. 104. 104. 105. 106. 108. 110. 112. + 114. 119. 119. 120. 121. 123. 124. 125. 125. 125. 126. 128. 129. + 129. 128. 126. 124. 128. 129. 129. 130. 130. 129. 129. 128. 131. + 130. 130. 129. 129. 130. 130. 131. 129. 129. 129. 129. 130. 131. + 132. 132. 132. 133. 133. 131. 129. 127. 127. 128. 121. 122. 122. + 123. 124. 125. 126. 126. 128. 125. 122. 123. 125. 127. 126. 124. + 130. 129. 128. 128. 129. 130. 132. 133. 130. 130. 130. 130. 129. + 128. 127. 126. 127. 127. 127. 126. 126. 125. 125. 125. 126. 126. + 126. 127. 127. 128. 128. 129. 128. 125. 122. 120. 119. 117. 115. + 113. 110. 110. 108. 108. 111. 118. 128. 135. 139. 144. 150. 154. + 156. 158. 160. 161. 162. 161. 159. 158. 157. 157. 158. 159. 159. + 159. 158. 158. 157. 156. 155. 155. 157. 156. 155. 155. 154. 154. + 155. 155. 149. 155. 156. 150. 146. 146. 146. 144. 152. 178. 203. + 211. 213. 218. 222. 221. 221. 207. 171. 127. 105. 109. 115. 115. + 113. 115. 117. 119. 120. 120. 120. 119. 122. 124. 127. 129. 131. + 131. 131. 130. 94. 57. 36. 47. 53. 41. 39. 52. 46. 50. 54. 53. 50. + 49. 51. 54. 158. 158. 158. 159. 159. 159. 160. 160. 160. 161. 162. + 164. 166. 168. 169. 170. 167. 166. 165. 161. 158. 156. 157. 158. + 162. 163. 160. 153. 146. 136. 120. 105. 95. 91. 90. 94. 98. 98. 100. + 103. 105. 106. 106. 106. 105. 103. 101. 100. 101. 101. 102. 104. + 106. 109. 112. 113. 120. 120. 121. 122. 123. 123. 124. 124. 126. + 127. 128. 129. 129. 129. 129. 128. 128. 127. 126. 126. 127. 129. + 131. 132. 134. 134. 134. 132. 131. 130. 131. 133. 130. 130. 130. + 130. 130. 130. 130. 130. 133. 133. 132. 131. 129. 127. 124. 123. + 122. 121. 119. 118. 118. 120. 122. 123. 126. 125. 125. 124. 123. + 122. 121. 120. 124. 126. 129. 131. 131. 130. 128. 126. 132. 131. + 130. 129. 128. 127. 127. 127. 127. 126. 125. 124. 125. 126. 127. + 128. 126. 126. 126. 126. 126. 126. 126. 126. 128. 127. 125. 122. + 120. 117. 115. 114. 114. 111. 108. 108. 111. 118. 126. 131. 139. + 142. 148. 152. 154. 156. 158. 160. 161. 160. 158. 157. 156. 157. + 158. 158. 155. 156. 156. 157. 157. 158. 158. 159. 155. 155. 154. + 154. 154. 155. 156. 156. 154. 153. 152. 152. 151. 149. 146. 143. + 141. 157. 183. 206. 213. 211. 215. 224. 222. 219. 212. 172. 120. + 109. 118. 111. 114. 116. 118. 119. 120. 120. 120. 119. 119. 124. + 127. 129. 133. 132. 120. 104. 57. 51. 44. 43. 47. 51. 51. 49. 51. + 51. 50. 50. 50. 51. 52. 53. 158. 158. 159. 159. 159. 160. 160. 161. + 160. 161. 162. 164. 166. 167. 168. 168. 166. 166. 164. 161. 157. + 156. 157. 159. 161. 162. 159. 153. 146. 135. 119. 104. 93. 89. 88. + 93. 97. 98. 100. 104. 104. 105. 105. 104. 104. 103. 102. 101. 102. + 102. 103. 105. 108. 110. 113. 114. 119. 120. 120. 121. 122. 123. + 123. 124. 125. 126. 127. 128. 128. 128. 128. 128. 127. 126. 126. + 126. 127. 128. 130. 131. 131. 131. 130. 129. 128. 128. 128. 129. + 130. 130. 130. 130. 130. 130. 130. 130. 132. 132. 131. 130. 128. + 126. 125. 124. 126. 124. 122. 120. 120. 123. 125. 127. 126. 126. + 125. 125. 126. 126. 127. 128. 126. 126. 128. 129. 130. 131. 131. + 131. 133. 132. 131. 129. 128. 127. 127. 127. 129. 128. 126. 125. + 124. 125. 125. 126. 126. 126. 126. 126. 126. 126. 126. 126. 127. + 126. 124. 122. 120. 118. 116. 115. 114. 111. 108. 108. 111. 118. + 126. 131. 138. 142. 147. 151. 153. 155. 158. 160. 160. 159. 158. + 157. 156. 157. 157. 158. 156. 156. 156. 157. 157. 157. 157. 157. + 156. 155. 155. 155. 155. 155. 156. 156. 154. 153. 152. 152. 151. + 150. 146. 143. 140. 151. 172. 196. 210. 213. 217. 222. 225. 220. + 214. 187. 139. 106. 102. 106. 110. 112. 115. 118. 121. 123. 124. + 124. 127. 127. 128. 130. 132. 120. 91. 63. 48. 44. 40. 41. 46. 51. + 51. 49. 52. 51. 51. 50. 50. 50. 51. 51. 160. 159. 159. 159. 159. + 160. 161. 162. 161. 162. 164. 166. 166. 166. 166. 165. 165. 165. + 163. 160. 157. 156. 158. 161. 160. 161. 158. 152. 145. 134. 118. + 104. 90. 86. 86. 92. 96. 98. 100. 104. 104. 103. 102. 102. 102. 102. + 102. 103. 103. 103. 104. 106. 109. 111. 114. 115. 118. 119. 119. + 120. 121. 122. 122. 123. 124. 125. 126. 127. 127. 127. 127. 126. + 125. 125. 125. 125. 126. 127. 129. 130. 130. 129. 128. 127. 127. + 127. 128. 128. 130. 130. 130. 130. 130. 129. 129. 129. 130. 129. + 129. 128. 127. 126. 126. 125. 126. 125. 122. 121. 121. 122. 124. + 126. 127. 126. 124. 121. 120. 120. 120. 120. 128. 127. 127. 128. + 129. 130. 131. 132. 134. 133. 131. 130. 128. 127. 127. 127. 131. + 129. 128. 126. 125. 124. 124. 124. 126. 126. 126. 126. 126. 126. + 126. 126. 125. 124. 123. 121. 120. 118. 117. 116. 114. 111. 108. + 107. 111. 117. 125. 130. 137. 141. 146. 150. 152. 154. 156. 158. + 159. 158. 157. 156. 156. 156. 157. 157. 157. 157. 157. 156. 156. + 156. 156. 156. 156. 156. 156. 156. 156. 155. 156. 156. 154. 153. + 151. 151. 151. 150. 147. 144. 140. 143. 156. 181. 204. 216. 219. + 219. 224. 222. 218. 207. 171. 117. 92. 104. 108. 109. 113. 117. 120. + 123. 125. 126. 124. 130. 134. 130. 117. 92. 60. 35. 45. 43. 42. 46. + 52. 57. 57. 55. 53. 52. 51. 50. 49. 49. 49. 49. 161. 160. 159. 159. + 159. 161. 162. 163. 164. 165. 166. 167. 167. 166. 164. 163. 163. + 163. 162. 159. 157. 157. 159. 162. 160. 160. 158. 151. 144. 134. + 117. 103. 88. 84. 84. 90. 96. 98. 101. 105. 103. 102. 101. 100. 100. + 101. 103. 104. 102. 103. 104. 106. 108. 111. 113. 115. 118. 118. + 119. 119. 120. 121. 122. 122. 123. 124. 125. 126. 126. 126. 126. + 125. 124. 124. 125. 125. 126. 127. 128. 128. 131. 130. 128. 128. + 129. 130. 129. 129. 130. 130. 130. 129. 129. 129. 129. 128. 128. + 128. 127. 127. 126. 126. 126. 127. 126. 126. 125. 124. 123. 122. + 122. 121. 125. 123. 121. 119. 118. 119. 120. 121. 125. 126. 126. + 127. 128. 128. 129. 129. 134. 133. 131. 129. 128. 127. 127. 127. + 129. 129. 128. 127. 126. 125. 125. 125. 126. 126. 126. 126. 126. + 126. 126. 126. 124. 123. 122. 121. 120. 118. 117. 117. 114. 111. + 108. 107. 110. 117. 124. 129. 136. 140. 145. 149. 150. 152. 154. + 156. 157. 157. 156. 156. 156. 156. 156. 156. 157. 157. 156. 156. + 155. 154. 154. 154. 156. 156. 156. 156. 156. 155. 155. 154. 154. + 152. 150. 150. 150. 149. 147. 145. 141. 137. 143. 166. 195. 215. + 220. 218. 219. 226. 222. 218. 201. 147. 103. 102. 108. 109. 112. + 114. 117. 119. 121. 122. 118. 131. 137. 120. 88. 59. 45. 42. 43. 44. + 46. 51. 57. 60. 59. 57. 54. 53. 51. 49. 48. 47. 47. 47. 162. 161. + 160. 159. 160. 161. 163. 164. 167. 168. 168. 167. 166. 164. 162. + 160. 160. 161. 161. 160. 158. 158. 160. 162. 160. 160. 158. 151. + 144. 134. 117. 103. 87. 83. 83. 90. 95. 98. 101. 105. 103. 102. 101. + 100. 100. 101. 103. 104. 101. 101. 102. 104. 107. 110. 112. 113. + 118. 118. 119. 119. 120. 121. 122. 122. 123. 123. 124. 125. 126. + 126. 125. 125. 123. 124. 125. 126. 127. 127. 127. 128. 131. 128. + 126. 127. 129. 130. 130. 128. 130. 130. 130. 129. 129. 128. 128. + 127. 128. 128. 126. 126. 126. 126. 127. 128. 125. 125. 126. 126. + 125. 123. 120. 118. 117. 117. 118. 118. 120. 123. 125. 127. 117. + 119. 122. 125. 128. 129. 129. 129. 132. 131. 130. 128. 127. 127. + 127. 127. 127. 127. 127. 128. 128. 127. 127. 127. 126. 126. 126. + 126. 126. 126. 126. 126. 123. 123. 122. 120. 119. 118. 117. 116. + 114. 112. 108. 107. 110. 116. 123. 128. 135. 139. 144. 147. 149. + 150. 152. 154. 155. 155. 156. 156. 156. 156. 156. 156. 156. 156. + 156. 155. 154. 154. 153. 153. 155. 155. 156. 156. 156. 154. 153. + 152. 153. 151. 149. 148. 148. 148. 147. 145. 143. 137. 138. 154. + 183. 208. 218. 217. 215. 230. 224. 217. 215. 180. 126. 100. 106. + 107. 108. 111. 114. 117. 119. 120. 131. 131. 120. 94. 61. 40. 41. + 51. 41. 43. 47. 51. 55. 56. 54. 52. 53. 52. 50. 49. 47. 46. 46. 45. + 164. 162. 161. 159. 160. 162. 164. 166. 170. 169. 167. 164. 162. + 160. 158. 157. 156. 158. 160. 161. 160. 159. 160. 161. 160. 161. + 158. 152. 145. 134. 118. 104. 87. 84. 84. 90. 96. 98. 101. 105. 104. + 103. 102. 102. 102. 102. 102. 103. 100. 101. 102. 104. 106. 109. + 111. 113. 118. 119. 119. 120. 121. 122. 122. 123. 123. 124. 125. + 126. 126. 126. 125. 125. 124. 124. 126. 127. 128. 128. 128. 128. + 129. 126. 123. 124. 128. 130. 128. 126. 130. 130. 129. 129. 128. + 127. 127. 127. 130. 129. 127. 126. 126. 126. 128. 129. 120. 121. + 121. 122. 122. 122. 122. 121. 120. 120. 119. 118. 117. 116. 114. + 114. 115. 116. 119. 122. 125. 128. 129. 130. 128. 128. 127. 126. + 126. 127. 128. 128. 126. 126. 127. 128. 129. 129. 128. 128. 126. + 126. 126. 126. 126. 126. 126. 126. 124. 123. 122. 120. 119. 117. + 116. 115. 114. 112. 108. 107. 109. 115. 123. 127. 134. 138. 142. + 146. 147. 148. 150. 152. 153. 154. 155. 156. 156. 156. 155. 155. + 154. 154. 154. 154. 154. 153. 153. 153. 153. 154. 155. 155. 155. + 153. 151. 150. 151. 149. 146. 145. 146. 146. 145. 144. 143. 140. + 138. 146. 167. 194. 211. 216. 215. 230. 226. 214. 216. 202. 153. + 107. 102. 103. 105. 109. 113. 117. 121. 123. 143. 119. 88. 63. 48. + 40. 41. 44. 46. 48. 52. 55. 56. 56. 54. 52. 52. 51. 49. 48. 46. 45. + 45. 45. 165. 163. 161. 160. 160. 162. 165. 167. 170. 167. 163. 159. + 156. 154. 154. 154. 152. 156. 160. 163. 162. 161. 160. 160. 161. + 162. 159. 153. 146. 135. 119. 104. 89. 85. 85. 91. 96. 98. 101. 104. + 104. 105. 105. 104. 104. 103. 102. 101. 101. 102. 103. 105. 107. + 110. 112. 114. 119. 120. 120. 121. 122. 123. 123. 124. 124. 124. + 125. 126. 127. 127. 126. 126. 124. 125. 127. 128. 129. 129. 129. + 128. 130. 126. 123. 124. 129. 131. 130. 127. 130. 130. 129. 129. + 128. 127. 126. 126. 132. 131. 128. 127. 126. 127. 128. 129. 128. + 127. 125. 125. 128. 133. 139. 143. 144. 144. 143. 140. 136. 131. + 127. 124. 127. 125. 122. 120. 119. 121. 124. 126. 124. 124. 124. + 125. 125. 127. 128. 129. 127. 128. 129. 129. 129. 128. 127. 126. + 126. 126. 126. 126. 126. 126. 126. 126. 125. 124. 122. 120. 118. + 116. 114. 113. 115. 112. 108. 106. 109. 115. 122. 127. 134. 137. + 142. 144. 146. 147. 149. 150. 152. 153. 154. 155. 156. 155. 155. + 154. 153. 153. 153. 153. 153. 154. 154. 154. 152. 153. 154. 154. + 153. 151. 149. 147. 149. 147. 144. 143. 144. 145. 144. 143. 142. + 144. 142. 140. 152. 177. 201. 214. 218. 224. 226. 219. 216. 214. + 183. 134. 104. 105. 107. 109. 113. 118. 121. 124. 121. 91. 60. 46. + 45. 44. 42. 42. 50. 53. 56. 58. 59. 58. 56. 56. 51. 50. 48. 47. 46. + 45. 45. 45. 165. 164. 161. 160. 160. 162. 165. 167. 169. 166. 160. + 155. 151. 150. 150. 151. 150. 154. 161. 164. 164. 161. 159. 159. + 162. 163. 160. 153. 146. 136. 120. 105. 90. 86. 86. 92. 96. 98. 100. + 104. 105. 106. 106. 106. 105. 103. 101. 100. 103. 103. 104. 106. + 108. 111. 114. 115. 120. 120. 121. 122. 123. 123. 124. 124. 124. + 125. 126. 127. 127. 127. 127. 126. 124. 126. 128. 129. 130. 130. + 129. 129. 133. 129. 125. 127. 132. 134. 133. 129. 130. 130. 129. + 128. 127. 127. 126. 125. 134. 132. 129. 127. 126. 127. 128. 129. + 146. 143. 138. 137. 143. 153. 165. 172. 171. 173. 175. 177. 177. + 174. 171. 169. 144. 137. 128. 119. 114. 114. 117. 120. 122. 122. + 123. 123. 125. 126. 128. 129. 129. 130. 130. 130. 129. 127. 125. + 124. 126. 126. 126. 126. 126. 126. 126. 126. 126. 125. 123. 120. + 118. 115. 113. 112. 115. 112. 108. 106. 109. 115. 122. 126. 133. + 137. 141. 144. 145. 146. 148. 149. 151. 152. 154. 155. 156. 155. + 154. 154. 151. 152. 152. 153. 153. 154. 154. 155. 151. 152. 153. + 154. 153. 150. 148. 146. 148. 146. 143. 142. 143. 144. 143. 142. + 140. 146. 145. 138. 142. 165. 195. 212. 220. 218. 227. 226. 218. + 222. 205. 163. 110. 110. 110. 111. 114. 116. 119. 121. 82. 65. 48. + 43. 44. 43. 46. 50. 47. 50. 53. 55. 55. 54. 54. 54. 50. 49. 48. 46. + 46. 45. 46. 46. 166. 162. 158. 157. 160. 164. 168. 170. 168. 163. + 156. 151. 149. 148. 147. 146. 150. 156. 162. 164. 162. 159. 159. + 160. 165. 164. 159. 152. 146. 138. 122. 107. 93. 86. 83. 88. 94. 95. + 97. 99. 106. 105. 105. 104. 104. 103. 103. 103. 102. 103. 106. 109. + 111. 113. 114. 114. 117. 120. 122. 122. 120. 120. 122. 125. 127. + 127. 126. 126. 126. 127. 128. 129. 122. 129. 132. 130. 130. 133. + 131. 125. 128. 125. 127. 133. 132. 125. 121. 124. 134. 131. 128. + 128. 129. 128. 124. 119. 122. 131. 137. 138. 140. 146. 147. 143. + 144. 143. 149. 159. 163. 163. 167. 174. 176. 173. 173. 176. 183. + 187. 188. 187. 184. 185. 177. 159. 141. 130. 122. 117. 115. 118. + 122. 124. 122. 121. 124. 129. 127. 133. 135. 130. 128. 131. 132. + 128. 130. 129. 129. 128. 128. 127. 127. 127. 126. 124. 121. 119. + 119. 117. 115. 112. 115. 110. 108. 109. 109. 112. 120. 129. 134. + 138. 143. 145. 145. 144. 143. 143. 148. 150. 152. 154. 155. 156. + 155. 155. 150. 153. 155. 155. 152. 151. 153. 156. 155. 154. 152. + 150. 149. 148. 148. 148. 145. 144. 143. 143. 142. 142. 143. 143. + 142. 140. 142. 144. 142. 148. 175. 206. 210. 218. 221. 220. 223. + 226. 213. 195. 140. 112. 104. 111. 115. 127. 120. 89. 49. 46. 43. + 42. 44. 47. 49. 49. 53. 54. 55. 57. 57. 58. 58. 58. 46. 44. 45. 49. + 50. 47. 47. 50. 164. 161. 158. 158. 161. 165. 169. 170. 165. 162. + 155. 149. 144. 143. 143. 144. 149. 155. 162. 164. 162. 160. 160. + 161. 165. 164. 159. 152. 147. 138. 122. 106. 93. 87. 85. 90. 96. 98. + 99. 102. 105. 105. 104. 104. 103. 103. 103. 102. 103. 104. 106. 108. + 111. 113. 115. 116. 118. 120. 122. 122. 121. 121. 123. 125. 127. + 126. 126. 126. 126. 127. 128. 129. 127. 130. 130. 126. 128. 132. + 131. 127. 139. 130. 123. 122. 122. 122. 129. 137. 130. 130. 130. + 128. 128. 128. 129. 131. 136. 144. 149. 147. 146. 149. 149. 147. + 148. 150. 158. 167. 169. 166. 169. 175. 180. 178. 177. 177. 177. + 177. 176. 174. 175. 184. 190. 190. 185. 174. 156. 142. 124. 117. + 112. 115. 122. 124. 121. 117. 128. 132. 133. 131. 130. 131. 126. + 118. 128. 127. 127. 127. 126. 126. 125. 125. 125. 122. 120. 119. + 118. 117. 115. 113. 115. 111. 108. 109. 110. 112. 120. 130. 135. + 138. 143. 146. 145. 144. 143. 143. 148. 149. 151. 153. 155. 155. + 155. 154. 151. 153. 154. 153. 152. 152. 153. 154. 153. 152. 151. + 149. 148. 147. 147. 146. 144. 144. 143. 142. 141. 141. 142. 142. + 143. 140. 141. 143. 140. 143. 164. 188. 208. 215. 218. 218. 224. + 229. 219. 204. 170. 126. 108. 120. 122. 112. 88. 55. 45. 43. 41. 41. + 43. 46. 47. 47. 53. 54. 54. 54. 55. 54. 54. 54. 45. 42. 43. 46. 46. + 43. 42. 45. 161. 159. 158. 159. 163. 167. 169. 170. 162. 159. 154. + 145. 137. 135. 138. 142. 149. 155. 162. 165. 163. 161. 162. 163. + 165. 164. 159. 153. 147. 138. 121. 105. 91. 85. 83. 89. 95. 98. 100. + 102. 104. 103. 103. 103. 103. 102. 102. 102. 105. 105. 106. 107. + 110. 113. 116. 118. 119. 121. 122. 122. 122. 122. 124. 125. 126. + 126. 125. 125. 126. 126. 127. 128. 132. 131. 127. 124. 126. 131. + 131. 127. 133. 129. 127. 128. 128. 126. 128. 132. 125. 127. 128. + 125. 123. 126. 134. 141. 142. 150. 154. 150. 144. 143. 144. 144. + 149. 155. 164. 172. 171. 167. 168. 173. 180. 181. 181. 179. 175. + 171. 168. 167. 180. 183. 184. 187. 192. 195. 189. 180. 167. 151. + 129. 115. 112. 117. 123. 126. 120. 122. 122. 123. 127. 131. 128. + 122. 125. 125. 125. 125. 124. 124. 124. 124. 122. 120. 118. 118. + 118. 117. 115. 113. 115. 111. 108. 109. 110. 113. 121. 130. 135. + 139. 143. 146. 146. 144. 143. 143. 148. 149. 150. 152. 153. 154. + 154. 154. 153. 152. 151. 151. 152. 153. 152. 150. 150. 150. 149. + 148. 147. 146. 145. 144. 143. 142. 141. 141. 140. 140. 141. 141. + 144. 140. 139. 141. 138. 137. 148. 164. 199. 209. 216. 218. 224. + 230. 226. 217. 208. 153. 122. 126. 119. 92. 61. 38. 42. 42. 41. 43. + 46. 49. 49. 48. 54. 53. 53. 52. 51. 50. 49. 49. 50. 47. 47. 49. 48. + 44. 43. 46. 158. 158. 159. 162. 166. 169. 169. 168. 158. 156. 150. + 139. 130. 128. 135. 142. 148. 155. 162. 165. 164. 163. 163. 165. + 165. 164. 160. 153. 147. 138. 120. 104. 87. 81. 79. 85. 92. 95. 97. + 100. 102. 102. 102. 102. 102. 101. 101. 101. 107. 106. 106. 107. + 109. 113. 117. 119. 120. 121. 122. 122. 122. 123. 124. 125. 125. + 125. 124. 124. 125. 126. 127. 127. 133. 130. 125. 124. 128. 131. + 129. 126. 124. 124. 126. 128. 128. 126. 125. 125. 131. 130. 127. + 125. 125. 131. 141. 148. 141. 147. 151. 147. 142. 139. 142. 145. + 145. 153. 162. 166. 164. 162. 166. 171. 173. 177. 181. 180. 176. + 173. 172. 173. 184. 181. 175. 172. 178. 189. 197. 198. 197. 192. + 175. 147. 123. 114. 117. 123. 118. 119. 120. 121. 124. 129. 131. + 132. 124. 124. 124. 124. 124. 124. 124. 124. 120. 119. 117. 116. + 117. 117. 115. 113. 114. 110. 108. 109. 110. 113. 121. 131. 135. + 139. 144. 146. 146. 145. 144. 144. 147. 148. 149. 150. 152. 153. + 153. 153. 154. 151. 149. 149. 152. 152. 150. 147. 147. 147. 147. + 146. 145. 144. 143. 143. 142. 141. 140. 139. 139. 139. 140. 140. + 143. 139. 138. 140. 139. 136. 138. 144. 183. 200. 217. 222. 223. + 226. 228. 227. 223. 183. 144. 120. 94. 67. 50. 43. 43. 43. 45. 48. + 52. 54. 53. 51. 55. 54. 53. 51. 49. 48. 47. 47. 54. 50. 49. 50. 49. + 45. 44. 47. 158. 159. 162. 165. 169. 169. 167. 165. 155. 151. 143. + 130. 122. 124. 134. 144. 149. 155. 163. 166. 165. 164. 164. 165. + 165. 164. 160. 154. 148. 138. 120. 103. 86. 80. 78. 84. 91. 94. 96. + 99. 100. 100. 100. 100. 100. 101. 101. 101. 106. 106. 105. 106. 109. + 112. 116. 119. 120. 120. 120. 121. 123. 124. 124. 124. 124. 124. + 124. 124. 124. 125. 126. 126. 130. 127. 125. 127. 130. 130. 127. + 126. 127. 125. 121. 118. 121. 128. 136. 140. 141. 135. 129. 127. + 131. 139. 145. 149. 141. 144. 147. 148. 145. 144. 149. 154. 144. + 150. 155. 157. 156. 159. 165. 170. 166. 171. 176. 178. 176. 175. + 176. 178. 174. 181. 186. 185. 185. 189. 191. 190. 190. 201. 205. + 190. 164. 138. 116. 102. 119. 122. 127. 129. 127. 125. 126. 129. + 124. 124. 124. 124. 124. 124. 124. 124. 119. 117. 115. 115. 116. + 115. 113. 112. 113. 109. 107. 108. 109. 112. 121. 131. 136. 139. + 144. 147. 146. 145. 144. 144. 147. 147. 147. 148. 150. 151. 152. + 153. 154. 151. 148. 148. 150. 151. 148. 144. 145. 145. 146. 146. + 145. 144. 142. 141. 142. 141. 140. 139. 139. 139. 139. 139. 142. + 139. 139. 141. 141. 138. 136. 137. 164. 189. 215. 224. 221. 220. + 225. 231. 218. 212. 173. 111. 63. 43. 41. 45. 43. 44. 46. 50. 54. + 55. 54. 53. 56. 55. 53. 51. 49. 48. 48. 48. 51. 47. 45. 46. 45. 42. + 42. 45. 160. 161. 165. 169. 171. 169. 164. 159. 152. 144. 131. 119. + 114. 120. 134. 145. 151. 157. 164. 167. 166. 164. 164. 165. 165. + 165. 161. 155. 148. 138. 119. 102. 88. 82. 80. 85. 92. 94. 96. 99. + 98. 99. 99. 99. 99. 100. 100. 100. 104. 104. 105. 106. 109. 112. + 115. 117. 120. 119. 118. 120. 122. 123. 123. 122. 124. 123. 123. + 123. 123. 124. 125. 126. 127. 125. 126. 129. 130. 127. 127. 129. + 126. 130. 134. 136. 141. 147. 149. 148. 137. 131. 123. 123. 128. + 135. 139. 139. 138. 137. 138. 142. 144. 145. 150. 156. 146. 150. + 153. 152. 155. 161. 167. 168. 164. 167. 171. 173. 173. 174. 175. + 176. 174. 184. 191. 190. 188. 189. 190. 190. 191. 197. 200. 198. + 194. 180. 150. 121. 109. 112. 119. 126. 125. 121. 120. 122. 123. + 123. 123. 123. 124. 124. 124. 124. 119. 117. 115. 114. 114. 114. + 112. 110. 111. 107. 105. 106. 108. 111. 120. 130. 136. 140. 145. + 147. 147. 145. 145. 145. 146. 146. 146. 147. 148. 150. 151. 152. + 153. 151. 149. 148. 148. 147. 145. 144. 143. 144. 145. 146. 145. + 144. 142. 141. 142. 141. 140. 139. 139. 139. 139. 140. 141. 140. + 140. 142. 143. 141. 139. 137. 148. 174. 204. 219. 219. 217. 223. + 231. 219. 235. 193. 104. 48. 36. 38. 41. 43. 43. 45. 48. 52. 54. 53. + 52. 56. 54. 52. 50. 49. 50. 50. 51. 51. 47. 45. 47. 47. 45. 46. 50. + 162. 164. 168. 172. 172. 168. 160. 154. 147. 136. 119. 107. 106. + 117. 134. 146. 153. 159. 165. 168. 166. 164. 163. 165. 165. 165. + 161. 155. 149. 138. 118. 101. 88. 82. 79. 85. 90. 92. 94. 97. 97. + 97. 98. 98. 99. 99. 99. 100. 102. 102. 104. 106. 109. 111. 113. 114. + 119. 117. 116. 118. 121. 123. 122. 120. 123. 123. 122. 122. 123. + 124. 124. 125. 125. 124. 126. 129. 126. 123. 128. 136. 121. 133. + 146. 151. 154. 152. 144. 133. 126. 124. 121. 120. 123. 127. 131. + 133. 135. 129. 127. 133. 138. 140. 142. 147. 149. 152. 152. 152. + 157. 164. 165. 161. 168. 167. 168. 170. 173. 176. 176. 175. 184. + 186. 185. 180. 181. 187. 191. 192. 197. 196. 190. 188. 197. 203. + 190. 170. 130. 119. 111. 114. 118. 118. 119. 122. 120. 121. 121. + 121. 122. 122. 123. 123. 119. 117. 115. 114. 113. 112. 110. 107. + 109. 105. 103. 105. 107. 110. 119. 128. 136. 140. 145. 147. 147. + 146. 145. 145. 146. 145. 145. 145. 147. 149. 151. 152. 151. 151. + 151. 149. 146. 144. 143. 144. 143. 144. 145. 146. 146. 144. 142. + 141. 142. 142. 141. 140. 140. 140. 140. 140. 141. 142. 143. 142. + 143. 143. 141. 140. 140. 158. 185. 207. 217. 220. 224. 228. 227. + 236. 177. 83. 40. 40. 42. 41. 45. 45. 46. 48. 52. 54. 54. 52. 53. + 52. 50. 49. 49. 50. 52. 53. 51. 47. 46. 49. 50. 49. 52. 56. 164. + 166. 170. 173. 173. 167. 157. 150. 144. 130. 111. 99. 101. 115. 133. + 145. 154. 160. 166. 168. 166. 163. 163. 164. 165. 165. 162. 156. + 149. 138. 118. 101. 86. 80. 77. 82. 88. 89. 91. 93. 96. 97. 97. 98. + 98. 99. 99. 99. 100. 101. 104. 106. 109. 111. 112. 112. 119. 117. + 115. 117. 121. 122. 121. 119. 123. 122. 122. 122. 122. 123. 124. + 125. 125. 124. 126. 127. 123. 120. 129. 142. 127. 134. 137. 135. + 133. 133. 128. 119. 123. 125. 127. 126. 125. 126. 132. 137. 138. + 128. 124. 130. 137. 137. 139. 142. 150. 152. 152. 153. 159. 165. + 162. 153. 171. 169. 167. 170. 176. 180. 180. 179. 185. 185. 184. + 183. 186. 191. 188. 181. 184. 192. 195. 191. 195. 204. 202. 193. + 181. 151. 120. 109. 112. 115. 119. 122. 118. 119. 119. 120. 120. + 121. 121. 121. 120. 117. 115. 113. 113. 111. 108. 106. 108. 104. + 102. 104. 106. 109. 118. 128. 136. 140. 145. 147. 147. 146. 145. + 145. 145. 145. 144. 145. 146. 148. 150. 152. 150. 152. 152. 149. + 144. 141. 142. 144. 142. 144. 145. 147. 146. 145. 142. 141. 143. + 142. 141. 140. 140. 140. 141. 141. 141. 143. 144. 143. 142. 142. + 142. 141. 137. 148. 170. 196. 215. 224. 226. 227. 229. 218. 142. 52. + 29. 41. 45. 44. 50. 49. 49. 51. 54. 56. 56. 55. 50. 49. 48. 47. 48. + 50. 53. 55. 46. 42. 42. 45. 47. 47. 50. 55. 168. 173. 176. 173. 169. + 164. 155. 145. 131. 121. 101. 85. 92. 117. 136. 141. 155. 162. 167. + 166. 165. 166. 164. 160. 165. 165. 162. 156. 150. 139. 121. 104. 85. + 78. 75. 79. 86. 89. 93. 96. 93. 93. 95. 96. 98. 99. 100. 101. 103. + 103. 103. 105. 106. 108. 110. 111. 119. 116. 114. 116. 119. 121. + 121. 119. 124. 124. 123. 122. 122. 122. 123. 123. 123. 132. 118. + 126. 115. 134. 142. 169. 110. 118. 127. 129. 126. 121. 120. 121. + 123. 123. 122. 122. 124. 127. 132. 135. 127. 128. 129. 132. 135. + 138. 141. 142. 149. 146. 145. 149. 155. 158. 156. 152. 164. 165. + 166. 168. 171. 177. 184. 189. 184. 188. 187. 183. 184. 190. 192. + 189. 188. 189. 192. 194. 195. 195. 195. 195. 198. 189. 160. 122. + 107. 114. 114. 104. 111. 117. 129. 127. 114. 114. 121. 117. 119. + 118. 117. 115. 113. 112. 110. 110. 109. 104. 101. 102. 105. 109. + 120. 131. 136. 140. 146. 149. 149. 147. 146. 146. 144. 144. 145. + 146. 146. 146. 145. 145. 149. 152. 154. 152. 147. 142. 141. 141. + 140. 140. 141. 143. 146. 146. 145. 143. 144. 144. 143. 141. 141. + 141. 141. 141. 141. 142. 143. 144. 145. 144. 143. 142. 143. 141. + 154. 185. 210. 220. 223. 227. 231. 166. 82. 32. 33. 51. 50. 36. 45. + 50. 54. 55. 54. 53. 56. 58. 53. 46. 39. 40. 47. 52. 51. 47. 42. 43. + 43. 44. 50. 55. 50. 41. 167. 172. 173. 169. 165. 160. 150. 140. 126. + 112. 91. 81. 91. 115. 134. 143. 154. 162. 167. 166. 165. 166. 164. + 161. 165. 165. 160. 154. 148. 138. 120. 104. 83. 77. 74. 80. 86. 89. + 92. 95. 95. 95. 96. 97. 98. 99. 100. 101. 102. 102. 103. 104. 105. + 107. 109. 110. 118. 116. 114. 115. 118. 120. 120. 119. 123. 123. + 122. 122. 122. 123. 124. 124. 127. 121. 134. 116. 122. 126. 153. + 143. 99. 107. 117. 122. 121. 119. 118. 119. 124. 122. 121. 122. 125. + 130. 133. 135. 125. 127. 130. 134. 136. 137. 137. 136. 142. 141. + 141. 145. 151. 156. 156. 155. 170. 172. 174. 176. 178. 180. 185. + 188. 181. 185. 186. 183. 184. 189. 191. 188. 188. 190. 192. 194. + 196. 196. 196. 196. 193. 195. 194. 178. 143. 110. 102. 111. 118. + 107. 105. 107. 109. 118. 122. 112. 117. 116. 115. 114. 112. 110. + 109. 108. 109. 104. 101. 102. 104. 109. 119. 130. 138. 143. 148. + 152. 152. 150. 149. 149. 144. 145. 145. 145. 145. 144. 144. 144. + 144. 147. 151. 151. 148. 144. 142. 142. 140. 140. 141. 144. 146. + 146. 145. 143. 144. 143. 142. 141. 141. 141. 142. 142. 141. 142. + 143. 144. 145. 144. 143. 143. 146. 143. 142. 158. 192. 223. 227. + 215. 173. 104. 48. 42. 47. 37. 35. 46. 45. 48. 52. 54. 54. 54. 55. + 55. 49. 46. 45. 46. 50. 51. 48. 44. 48. 46. 46. 51. 55. 52. 42. 34. + 169. 171. 170. 165. 160. 154. 144. 133. 117. 97. 78. 77. 93. 113. + 132. 144. 154. 162. 167. 166. 166. 167. 165. 161. 166. 164. 159. + 151. 145. 136. 120. 104. 81. 75. 74. 80. 87. 89. 91. 93. 98. 98. 98. + 99. 99. 100. 100. 100. 101. 101. 102. 103. 105. 107. 108. 110. 116. + 114. 113. 114. 116. 118. 118. 118. 122. 121. 121. 121. 122. 123. + 124. 125. 126. 117. 134. 117. 121. 127. 146. 115. 103. 109. 117. + 122. 122. 120. 121. 122. 125. 122. 120. 122. 127. 132. 134. 134. + 125. 128. 132. 135. 136. 135. 132. 130. 136. 137. 139. 143. 148. + 154. 159. 161. 169. 172. 175. 177. 177. 177. 178. 180. 178. 182. + 184. 184. 186. 189. 190. 188. 188. 190. 193. 195. 197. 198. 198. + 197. 195. 194. 199. 205. 191. 155. 118. 98. 111. 106. 110. 113. 106. + 109. 118. 117. 115. 115. 113. 112. 110. 109. 108. 107. 110. 105. + 102. 102. 104. 108. 118. 128. 139. 143. 149. 152. 153. 151. 150. + 150. 146. 145. 144. 143. 142. 141. 141. 142. 137. 142. 147. 150. + 149. 146. 144. 143. 141. 141. 142. 144. 146. 147. 145. 142. 143. + 142. 142. 141. 142. 142. 143. 144. 142. 142. 143. 144. 145. 145. + 145. 144. 150. 149. 140. 144. 181. 219. 209. 173. 96. 51. 29. 47. + 54. 34. 31. 50. 47. 47. 49. 52. 54. 54. 52. 50. 46. 48. 51. 53. 53. + 49. 44. 41. 46. 46. 52. 61. 56. 40. 27. 25. 172. 173. 169. 162. 156. + 150. 137. 126. 104. 84. 70. 79. 98. 114. 130. 143. 154. 161. 167. + 167. 166. 167. 166. 162. 166. 163. 157. 149. 143. 135. 119. 104. 79. + 74. 74. 81. 88. 90. 91. 93. 100. 100. 100. 100. 100. 100. 100. 100. + 100. 101. 101. 102. 104. 106. 108. 109. 114. 114. 113. 114. 115. + 116. 117. 118. 120. 120. 120. 121. 122. 123. 125. 126. 120. 126. + 116. 129. 123. 137. 116. 108. 116. 118. 120. 120. 119. 119. 121. + 123. 128. 124. 121. 123. 128. 132. 132. 131. 129. 131. 133. 135. + 135. 134. 131. 129. 136. 138. 141. 144. 147. 153. 160. 165. 165. + 168. 171. 173. 173. 173. 175. 176. 178. 181. 184. 186. 189. 191. + 191. 190. 189. 191. 193. 196. 198. 198. 198. 198. 194. 196. 194. + 198. 212. 208. 164. 113. 98. 93. 103. 112. 105. 104. 111. 114. 114. + 113. 112. 111. 110. 109. 108. 107. 111. 106. 102. 102. 103. 107. + 117. 127. 137. 142. 148. 151. 152. 150. 149. 149. 148. 146. 144. + 141. 139. 137. 137. 137. 134. 138. 144. 149. 150. 148. 145. 143. + 142. 142. 142. 144. 146. 147. 145. 142. 142. 142. 142. 142. 142. + 143. 144. 145. 142. 143. 144. 145. 145. 146. 146. 146. 147. 151. + 149. 153. 175. 187. 152. 102. 46. 44. 42. 44. 46. 46. 46. 47. 51. + 49. 48. 50. 53. 52. 48. 43. 46. 51. 56. 56. 52. 47. 44. 43. 44. 50. + 65. 71. 53. 28. 26. 39. 175. 174. 169. 161. 154. 145. 130. 116. 93. + 77. 71. 84. 103. 117. 130. 141. 154. 161. 167. 167. 167. 168. 167. + 163. 165. 163. 157. 149. 143. 134. 119. 104. 79. 74. 74. 81. 88. 91. + 92. 94. 101. 101. 101. 101. 100. 100. 100. 100. 100. 101. 101. 102. + 104. 106. 108. 109. 113. 113. 114. 114. 114. 115. 117. 118. 120. + 120. 120. 120. 121. 123. 124. 125. 119. 132. 110. 132. 146. 136. 96. + 116. 118. 117. 114. 112. 110. 112. 116. 119. 129. 126. 124. 124. + 127. 129. 129. 127. 134. 134. 134. 134. 134. 134. 133. 133. 138. + 139. 141. 143. 145. 150. 156. 160. 164. 166. 168. 170. 172. 175. + 179. 182. 181. 182. 185. 189. 191. 191. 192. 192. 190. 192. 194. + 196. 197. 198. 197. 197. 189. 201. 204. 197. 199. 205. 195. 175. + 123. 93. 81. 91. 98. 103. 106. 103. 113. 112. 111. 110. 109. 108. + 107. 107. 111. 105. 101. 102. 103. 106. 116. 126. 138. 142. 148. + 152. 153. 152. 151. 151. 150. 148. 144. 140. 136. 133. 131. 129. + 130. 134. 140. 147. 150. 149. 146. 143. 143. 143. 143. 145. 147. + 147. 144. 142. 142. 142. 142. 142. 143. 144. 145. 146. 143. 144. + 144. 145. 146. 147. 148. 148. 144. 148. 156. 162. 159. 134. 86. 45. + 35. 51. 54. 40. 38. 51. 56. 49. 55. 52. 49. 49. 50. 49. 44. 40. 50. + 53. 56. 54. 49. 46. 47. 50. 54. 62. 72. 66. 41. 26. 50. 86. 173. + 172. 166. 158. 150. 139. 120. 104. 86. 78. 77. 87. 104. 119. 132. + 140. 154. 161. 167. 167. 167. 169. 167. 164. 164. 163. 157. 150. + 144. 135. 119. 103. 81. 75. 74. 81. 88. 91. 94. 96. 100. 100. 100. + 100. 100. 100. 100. 100. 101. 101. 102. 103. 105. 107. 108. 110. + 113. 114. 115. 114. 114. 114. 117. 119. 121. 120. 120. 120. 121. + 122. 123. 124. 127. 126. 124. 127. 167. 122. 101. 121. 113. 112. + 109. 108. 109. 113. 117. 120. 126. 126. 125. 125. 125. 126. 127. + 127. 134. 134. 133. 133. 134. 134. 135. 136. 138. 137. 138. 140. + 142. 146. 149. 150. 158. 160. 163. 166. 169. 174. 180. 184. 185. + 183. 185. 190. 192. 191. 191. 194. 192. 193. 195. 196. 196. 196. + 195. 194. 197. 195. 196. 196. 190. 186. 196. 213. 187. 152. 129. + 117. 97. 87. 98. 110. 110. 110. 109. 108. 107. 106. 106. 105. 109. + 104. 101. 101. 102. 106. 117. 127. 141. 145. 152. 156. 156. 156. + 155. 155. 151. 150. 146. 141. 135. 129. 124. 121. 124. 127. 133. + 141. 147. 149. 147. 145. 144. 143. 144. 145. 147. 147. 144. 142. + 144. 143. 143. 143. 143. 144. 144. 145. 144. 144. 144. 145. 146. + 147. 149. 150. 151. 153. 160. 158. 133. 89. 53. 36. 42. 46. 46. 41. + 39. 45. 52. 57. 56. 53. 50. 48. 47. 46. 45. 43. 54. 54. 53. 50. 47. + 48. 52. 57. 66. 65. 59. 44. 28. 39. 86. 134. 168. 166. 160. 152. + 144. 130. 109. 90. 83. 83. 83. 86. 98. 118. 134. 140. 154. 161. 167. + 167. 168. 169. 168. 165. 164. 163. 159. 152. 146. 136. 119. 102. 83. + 77. 75. 81. 88. 92. 96. 99. 99. 99. 99. 99. 100. 100. 100. 100. 102. + 102. 103. 104. 105. 107. 109. 110. 113. 115. 116. 116. 114. 114. + 117. 120. 122. 121. 121. 120. 120. 121. 122. 122. 131. 116. 133. + 137. 148. 116. 114. 112. 109. 109. 110. 113. 116. 118. 120. 120. + 119. 123. 126. 126. 123. 123. 127. 131. 129. 130. 132. 134. 135. + 136. 135. 135. 138. 136. 136. 139. 144. 147. 146. 145. 154. 158. + 163. 168. 172. 176. 180. 183. 187. 184. 184. 189. 190. 188. 189. + 194. 193. 194. 195. 195. 195. 194. 192. 191. 196. 188. 186. 193. + 198. 199. 204. 212. 224. 213. 209. 186. 128. 84. 88. 109. 106. 106. + 105. 105. 104. 103. 103. 102. 108. 103. 100. 100. 102. 107. 117. + 128. 141. 146. 152. 156. 157. 157. 156. 156. 153. 151. 148. 142. + 135. 126. 118. 113. 114. 117. 123. 133. 142. 148. 149. 148. 145. + 144. 144. 146. 147. 147. 144. 142. 145. 145. 144. 143. 143. 143. + 144. 144. 145. 145. 144. 145. 146. 148. 150. 151. 156. 159. 158. + 140. 101. 61. 45. 47. 46. 42. 41. 42. 44. 46. 50. 55. 53. 52. 49. + 46. 44. 45. 49. 52. 55. 53. 50. 47. 47. 51. 57. 61. 72. 61. 44. 32. + 39. 74. 123. 160. 163. 161. 156. 148. 139. 124. 101. 81. 83. 88. 86. + 83. 93. 116. 135. 141. 154. 161. 167. 167. 168. 169. 168. 165. 163. + 163. 160. 154. 148. 137. 119. 102. 84. 78. 75. 81. 88. 93. 97. 101. + 98. 98. 98. 99. 99. 100. 100. 100. 103. 103. 103. 105. 106. 108. + 110. 111. 113. 115. 117. 116. 114. 115. 118. 121. 122. 122. 121. + 120. 120. 120. 121. 121. 130. 112. 128. 156. 111. 120. 120. 100. + 104. 106. 110. 115. 119. 119. 116. 114. 113. 120. 125. 125. 122. + 122. 128. 134. 123. 126. 131. 135. 137. 136. 135. 133. 140. 137. + 136. 140. 147. 151. 148. 144. 157. 163. 171. 177. 181. 183. 185. + 186. 188. 183. 183. 187. 188. 185. 188. 194. 194. 194. 195. 195. + 194. 192. 190. 189. 178. 195. 204. 201. 207. 222. 224. 213. 219. + 219. 234. 228. 170. 106. 83. 86. 103. 103. 103. 102. 101. 101. 100. + 100. 107. 102. 99. 100. 102. 107. 118. 129. 139. 144. 150. 155. 156. + 155. 155. 155. 153. 152. 149. 143. 134. 124. 114. 108. 106. 109. + 116. 127. 139. 147. 150. 150. 145. 144. 145. 146. 147. 147. 144. + 142. 146. 146. 145. 144. 143. 143. 143. 143. 145. 145. 144. 145. + 146. 148. 151. 152. 151. 157. 151. 120. 75. 44. 40. 48. 43. 47. 46. + 42. 47. 57. 55. 45. 49. 50. 49. 45. 43. 46. 52. 58. 54. 51. 48. 47. + 49. 54. 59. 63. 77. 61. 41. 39. 67. 114. 152. 170. 158. 159. 156. + 145. 127. 106. 90. 81. 80. 80. 82. 88. 101. 119. 135. 145. 154. 158. + 164. 168. 168. 167. 166. 166. 161. 162. 159. 152. 144. 133. 116. + 101. 79. 74. 72. 79. 87. 90. 93. 97. 98. 98. 99. 99. 99. 99. 99. 99. + 101. 101. 102. 103. 105. 108. 110. 111. 112. 112. 113. 114. 116. + 118. 121. 122. 118. 121. 124. 123. 120. 119. 120. 121. 124. 130. + 133. 127. 115. 107. 108. 112. 109. 111. 114. 115. 115. 116. 117. + 119. 128. 126. 122. 120. 120. 123. 127. 130. 123. 127. 130. 132. + 133. 133. 134. 135. 128. 134. 140. 142. 141. 142. 147. 152. 156. + 158. 167. 174. 177. 185. 187. 179. 180. 184. 187. 187. 185. 185. + 189. 193. 197. 193. 188. 185. 185. 187. 192. 195. 210. 209. 209. + 210. 211. 212. 214. 214. 218. 216. 221. 239. 219. 139. 81. 87. 84. + 104. 105. 100. 105. 97. 93. 109. 100. 100. 100. 99. 101. 108. 120. + 129. 138. 143. 150. 154. 155. 154. 153. 153. 151. 151. 149. 144. + 138. 128. 109. 92. 94. 92. 100. 118. 130. 135. 142. 151. 147. 145. + 142. 143. 146. 147. 146. 144. 143. 143. 143. 144. 144. 145. 145. + 145. 144. 144. 146. 149. 148. 145. 146. 150. 159. 154. 125. 81. 49. + 43. 47. 47. 42. 44. 47. 49. 51. 52. 52. 52. 49. 53. 50. 41. 41. 52. + 58. 56. 40. 49. 52. 45. 44. 56. 72. 80. 79. 50. 37. 65. 111. 144. + 160. 166. 157. 156. 150. 136. 117. 99. 86. 81. 83. 82. 83. 89. 101. + 118. 135. 145. 153. 158. 164. 168. 168. 167. 166. 166. 163. 163. + 159. 151. 143. 132. 116. 102. 82. 76. 74. 81. 88. 91. 94. 97. 98. + 98. 99. 99. 100. 100. 101. 101. 101. 101. 102. 103. 105. 108. 110. + 111. 114. 114. 114. 115. 116. 117. 119. 120. 119. 122. 123. 123. + 121. 120. 121. 123. 127. 128. 127. 119. 110. 106. 109. 114. 112. + 115. 117. 119. 119. 119. 121. 122. 118. 119. 121. 122. 122. 122. + 122. 121. 123. 126. 130. 131. 131. 131. 132. 133. 134. 137. 140. + 140. 138. 139. 145. 150. 151. 167. 165. 165. 185. 188. 181. 188. + 191. 187. 182. 183. 187. 191. 192. 192. 183. 181. 179. 181. 187. + 198. 209. 216. 212. 211. 210. 210. 210. 210. 210. 211. 208. 219. + 220. 222. 223. 192. 125. 71. 87. 98. 97. 92. 99. 104. 101. 100. 99. + 99. 98. 97. 99. 106. 118. 127. 138. 143. 150. 154. 155. 154. 153. + 153. 153. 153. 150. 145. 138. 127. 108. 91. 81. 80. 90. 111. 128. + 135. 140. 148. 149. 146. 143. 143. 145. 147. 146. 144. 143. 143. + 143. 144. 144. 145. 145. 145. 145. 145. 146. 148. 147. 147. 150. + 155. 157. 133. 92. 54. 36. 35. 37. 36. 45. 46. 49. 51. 52. 53. 53. + 52. 51. 49. 46. 44. 48. 54. 55. 51. 43. 48. 49. 48. 52. 63. 71. 73. + 63. 56. 66. 99. 133. 149. 155. 159. 156. 152. 141. 123. 102. 88. 82. + 82. 86. 85. 85. 90. 102. 118. 134. 144. 153. 158. 164. 167. 168. + 167. 166. 166. 164. 164. 158. 149. 141. 132. 117. 103. 84. 78. 76. + 82. 89. 92. 94. 97. 98. 98. 99. 100. 101. 102. 103. 103. 101. 101. + 102. 103. 105. 108. 110. 111. 116. 116. 115. 115. 115. 116. 117. + 118. 120. 122. 123. 122. 121. 122. 124. 126. 128. 125. 118. 110. + 105. 105. 110. 115. 114. 116. 119. 120. 121. 121. 123. 124. 116. + 117. 118. 119. 120. 121. 121. 121. 129. 132. 135. 136. 136. 135. + 135. 136. 135. 138. 139. 139. 138. 140. 146. 151. 163. 151. 167. + 177. 167. 182. 196. 177. 183. 186. 191. 194. 192. 186. 179. 174. + 171. 178. 190. 201. 209. 212. 211. 210. 211. 210. 209. 209. 208. + 209. 209. 210. 209. 219. 221. 215. 227. 234. 179. 98. 83. 86. 92. + 93. 93. 103. 105. 93. 97. 98. 97. 96. 97. 104. 116. 124. 138. 143. + 150. 154. 155. 154. 153. 153. 155. 155. 152. 146. 139. 127. 107. 90. + 67. 64. 74. 99. 122. 132. 137. 143. 150. 148. 145. 144. 145. 146. + 146. 145. 143. 143. 143. 144. 144. 145. 145. 145. 143. 144. 145. + 144. 145. 149. 154. 157. 154. 113. 65. 41. 39. 43. 45. 44. 48. 49. + 51. 53. 54. 54. 53. 53. 51. 44. 43. 49. 55. 54. 49. 46. 48. 50. 51. + 55. 64. 72. 71. 66. 59. 73. 103. 135. 150. 150. 150. 155. 153. 145. + 130. 109. 90. 80. 81. 85. 89. 87. 87. 90. 101. 117. 133. 144. 153. + 157. 163. 167. 168. 166. 166. 166. 166. 164. 158. 148. 140. 131. + 117. 104. 85. 79. 77. 82. 89. 91. 93. 96. 97. 98. 99. 100. 102. 103. + 104. 105. 101. 101. 102. 103. 105. 108. 110. 111. 115. 115. 115. + 115. 116. 117. 118. 119. 121. 122. 122. 122. 122. 124. 126. 127. + 125. 119. 110. 104. 103. 107. 111. 114. 113. 115. 118. 119. 119. + 119. 121. 122. 122. 119. 116. 114. 116. 121. 127. 130. 132. 135. + 138. 139. 138. 137. 137. 138. 133. 136. 139. 141. 142. 145. 150. + 153. 151. 173. 161. 155. 181. 181. 168. 184. 177. 187. 194. 190. + 177. 168. 168. 173. 190. 198. 209. 217. 218. 212. 202. 195. 207. + 207. 207. 207. 207. 208. 209. 210. 212. 208. 216. 219. 219. 229. + 211. 163. 91. 78. 87. 98. 91. 94. 101. 93. 97. 97. 96. 95. 96. 104. + 115. 124. 138. 143. 150. 154. 155. 154. 153. 153. 154. 155. 152. + 146. 140. 129. 110. 92. 61. 53. 59. 84. 111. 125. 133. 138. 150. + 148. 146. 145. 145. 145. 145. 146. 143. 143. 143. 144. 144. 145. + 145. 145. 140. 143. 143. 141. 145. 153. 155. 152. 115. 77. 42. 34. + 39. 40. 41. 45. 52. 53. 54. 55. 55. 54. 53. 52. 48. 42. 45. 56. 59. + 51. 44. 45. 51. 54. 59. 65. 72. 75. 72. 67. 79. 100. 130. 151. 151. + 144. 145. 153. 147. 136. 118. 98. 84. 80. 84. 89. 91. 89. 87. 90. + 100. 116. 133. 143. 152. 157. 163. 167. 167. 166. 165. 165. 166. + 165. 158. 149. 140. 131. 116. 103. 84. 78. 76. 81. 88. 90. 92. 95. + 97. 98. 99. 100. 102. 103. 104. 105. 101. 101. 102. 103. 105. 108. + 110. 111. 112. 113. 113. 114. 116. 118. 120. 121. 121. 121. 121. + 122. 123. 125. 126. 126. 117. 112. 107. 105. 107. 109. 111. 111. + 114. 116. 119. 119. 118. 118. 119. 120. 119. 118. 116. 116. 118. + 123. 128. 131. 129. 132. 135. 135. 135. 134. 134. 134. 135. 138. + 142. 144. 146. 147. 149. 150. 162. 148. 165. 176. 161. 176. 192. + 169. 187. 182. 173. 162. 159. 168. 186. 200. 218. 216. 211. 207. + 204. 203. 203. 203. 207. 206. 206. 205. 205. 206. 207. 207. 207. + 200. 211. 218. 211. 219. 223. 207. 137. 88. 72. 87. 89. 89. 96. 95. + 96. 96. 96. 95. 97. 104. 116. 125. 138. 143. 150. 154. 155. 154. + 153. 153. 152. 153. 151. 146. 141. 131. 113. 96. 64. 51. 48. 69. 96. + 114. 126. 134. 147. 147. 147. 146. 145. 145. 145. 145. 143. 143. + 143. 144. 144. 145. 145. 145. 140. 145. 146. 143. 150. 158. 152. + 137. 78. 57. 45. 49. 49. 40. 41. 51. 54. 54. 55. 55. 54. 53. 51. 49. + 45. 44. 51. 60. 57. 46. 42. 48. 50. 56. 64. 71. 73. 72. 74. 77. 107. + 123. 144. 153. 147. 139. 140. 147. 138. 125. 106. 90. 83. 84. 88. + 91. 91. 88. 86. 89. 99. 115. 132. 143. 152. 157. 163. 166. 167. 166. + 165. 165. 166. 165. 159. 150. 141. 131. 115. 101. 83. 77. 75. 81. + 88. 91. 93. 96. 98. 98. 99. 100. 101. 102. 103. 103. 101. 101. 102. + 103. 105. 108. 110. 111. 112. 112. 113. 114. 116. 119. 121. 122. + 121. 120. 121. 122. 125. 125. 124. 122. 109. 108. 107. 108. 110. + 112. 112. 111. 117. 119. 121. 120. 118. 117. 117. 118. 109. 112. + 118. 123. 126. 127. 125. 124. 130. 133. 136. 138. 137. 136. 137. + 138. 143. 144. 144. 145. 145. 145. 144. 144. 145. 167. 161. 160. + 184. 183. 170. 181. 178. 167. 158. 162. 179. 196. 206. 209. 209. + 208. 206. 205. 204. 204. 205. 206. 207. 206. 205. 204. 204. 203. + 204. 204. 205. 208. 214. 214. 216. 230. 232. 217. 199. 125. 70. 70. + 84. 90. 92. 93. 93. 94. 94. 94. 96. 105. 117. 127. 138. 143. 150. + 154. 155. 154. 153. 153. 151. 152. 151. 147. 142. 133. 115. 98. 68. + 51. 43. 58. 82. 102. 118. 130. 142. 144. 147. 148. 146. 144. 144. + 144. 143. 143. 143. 144. 144. 145. 145. 145. 143. 150. 151. 148. + 156. 160. 138. 108. 59. 55. 58. 64. 58. 46. 46. 56. 55. 55. 55. 54. + 53. 50. 48. 46. 45. 50. 56. 58. 52. 44. 45. 50. 47. 54. 65. 71. 71. + 73. 84. 97. 126. 137. 150. 153. 147. 140. 140. 143. 128. 113. 94. + 84. 85. 89. 92. 91. 90. 87. 85. 87. 98. 114. 132. 143. 152. 156. + 162. 166. 166. 165. 165. 164. 165. 165. 160. 151. 142. 131. 114. + 100. 83. 77. 76. 82. 89. 93. 95. 98. 98. 98. 99. 99. 100. 100. 101. + 101. 101. 101. 102. 103. 105. 108. 110. 111. 113. 113. 114. 114. + 116. 118. 119. 120. 120. 120. 120. 123. 126. 125. 121. 117. 105. + 107. 109. 111. 112. 113. 114. 114. 118. 119. 120. 119. 116. 113. + 113. 113. 107. 112. 120. 127. 131. 130. 128. 125. 134. 137. 140. + 142. 142. 142. 143. 144. 148. 146. 142. 140. 139. 141. 142. 143. + 151. 148. 165. 175. 169. 176. 179. 160. 157. 163. 175. 192. 207. + 212. 206. 199. 194. 200. 207. 212. 213. 208. 202. 197. 201. 201. + 201. 202. 203. 205. 207. 208. 209. 217. 214. 212. 222. 228. 225. + 224. 228. 174. 106. 74. 78. 83. 83. 89. 89. 90. 91. 92. 95. 104. + 117. 127. 138. 143. 150. 154. 155. 154. 153. 153. 153. 154. 152. + 148. 143. 133. 114. 98. 67. 49. 40. 51. 72. 92. 110. 125. 136. 141. + 146. 149. 147. 144. 143. 143. 143. 143. 143. 144. 144. 145. 145. + 145. 144. 152. 152. 149. 156. 154. 115. 69. 41. 41. 45. 49. 46. 40. + 42. 49. 54. 54. 54. 53. 51. 47. 44. 42. 50. 55. 57. 52. 48. 49. 50. + 50. 51. 54. 63. 71. 75. 84. 103. 122. 137. 145. 150. 149. 144. 143. + 148. 153. 120. 105. 87. 81. 86. 93. 93. 91. 89. 86. 84. 86. 97. 114. + 132. 143. 152. 156. 162. 166. 166. 165. 164. 164. 164. 164. 160. + 152. 143. 131. 114. 98. 83. 78. 77. 83. 91. 95. 97. 101. 98. 98. 99. + 99. 99. 99. 99. 99. 101. 101. 102. 103. 105. 108. 110. 111. 116. + 115. 115. 115. 115. 116. 117. 118. 119. 119. 120. 124. 126. 125. + 119. 114. 104. 107. 110. 111. 112. 113. 115. 118. 115. 117. 117. + 115. 112. 109. 108. 108. 115. 118. 122. 126. 130. 133. 134. 134. + 131. 135. 138. 140. 141. 141. 142. 143. 149. 143. 137. 133. 134. + 139. 144. 147. 146. 158. 164. 166. 173. 169. 157. 150. 153. 175. + 200. 210. 206. 199. 198. 201. 207. 208. 208. 208. 206. 203. 200. + 199. 192. 193. 196. 200. 204. 209. 213. 216. 211. 213. 206. 209. + 217. 204. 205. 234. 225. 209. 151. 92. 74. 71. 72. 86. 86. 87. 88. + 89. 94. 103. 117. 127. 138. 143. 150. 154. 155. 154. 153. 153. 156. + 156. 153. 148. 142. 132. 113. 96. 64. 48. 38. 49. 68. 86. 105. 121. + 132. 138. 146. 149. 148. 144. 143. 142. 143. 143. 143. 144. 144. + 145. 145. 145. 143. 151. 150. 147. 153. 145. 96. 40. 44. 41. 39. 42. + 46. 50. 54. 58. 54. 54. 53. 52. 49. 46. 42. 40. 55. 59. 55. 46. 46. + 53. 54. 48. 56. 57. 62. 72. 82. 96. 120. 142. 145. 149. 149. 142. + 138. 145. 158. 169. 98. 90. 81. 82. 89. 94. 91. 86. 92. 89. 87. 89. + 98. 114. 130. 140. 148. 156. 162. 163. 165. 168. 168. 166. 165. 165. + 159. 150. 142. 133. 118. 104. 86. 79. 77. 84. 92. 95. 95. 96. 102. + 100. 98. 97. 96. 98. 100. 101. 99. 99. 100. 101. 103. 106. 108. 109. + 112. 116. 119. 120. 117. 116. 117. 118. 118. 126. 125. 123. 128. + 124. 117. 118. 118. 114. 111. 109. 110. 113. 114. 115. 118. 116. + 114. 114. 116. 117. 117. 116. 124. 122. 123. 128. 134. 136. 134. + 130. 134. 134. 134. 135. 138. 141. 144. 145. 145. 141. 137. 137. + 141. 145. 147. 147. 160. 148. 159. 179. 165. 133. 137. 169. 192. + 199. 204. 204. 204. 207. 207. 204. 204. 204. 203. 201. 199. 198. + 197. 196. 205. 205. 204. 203. 202. 202. 201. 201. 200. 201. 204. + 207. 209. 211. 211. 211. 215. 222. 209. 167. 117. 85. 75. 74. 81. + 73. 94. 92. 85. 106. 119. 127. 138. 145. 153. 156. 156. 154. 153. + 154. 151. 154. 155. 152. 146. 134. 115. 98. 72. 48. 40. 50. 61. 78. + 98. 105. 124. 131. 141. 147. 148. 146. 143. 141. 140. 135. 136. 143. + 147. 144. 144. 148. 148. 146. 154. 162. 145. 103. 62. 43. 39. 38. + 39. 44. 51. 56. 58. 57. 55. 52. 48. 44. 43. 45. 49. 53. 62. 49. 45. + 54. 55. 48. 48. 57. 64. 64. 60. 72. 102. 124. 135. 145. 148. 146. + 144. 143. 145. 152. 160. 166. 95. 89. 84. 84. 90. 93. 91. 88. 92. + 89. 86. 88. 98. 113. 129. 140. 148. 156. 162. 163. 164. 168. 168. + 166. 164. 164. 159. 150. 142. 132. 117. 104. 86. 78. 75. 82. 90. 93. + 94. 96. 100. 100. 99. 98. 98. 98. 99. 100. 100. 100. 101. 102. 104. + 107. 109. 110. 112. 116. 119. 120. 118. 117. 118. 119. 123. 116. + 119. 130. 131. 118. 111. 116. 115. 114. 112. 111. 111. 112. 114. + 115. 118. 116. 115. 115. 117. 119. 119. 118. 122. 124. 126. 127. + 128. 129. 130. 132. 137. 137. 137. 137. 138. 139. 141. 142. 141. + 138. 134. 135. 139. 142. 144. 144. 148. 165. 170. 152. 137. 147. + 171. 188. 192. 198. 200. 199. 200. 204. 207. 206. 200. 200. 200. + 200. 199. 199. 199. 199. 201. 201. 201. 201. 202. 202. 202. 202. + 204. 205. 208. 210. 212. 212. 212. 212. 223. 215. 220. 228. 200. + 140. 88. 68. 72. 76. 86. 78. 88. 110. 111. 121. 138. 144. 152. 156. + 155. 154. 153. 154. 151. 154. 155. 152. 145. 134. 115. 98. 69. 49. + 41. 46. 47. 61. 84. 96. 120. 127. 138. 144. 146. 145. 144. 144. 150. + 143. 140. 143. 145. 142. 142. 145. 149. 149. 156. 155. 125. 77. 46. + 40. 39. 39. 41. 46. 52. 56. 57. 56. 56. 55. 51. 45. 42. 45. 53. 59. + 56. 47. 45. 51. 55. 53. 54. 59. 60. 64. 65. 82. 115. 136. 141. 148. + 150. 147. 145. 147. 154. 161. 164. 165. 89. 88. 87. 88. 90. 92. 91. + 90. 92. 89. 86. 88. 98. 113. 129. 140. 149. 156. 162. 163. 164. 167. + 167. 165. 163. 163. 158. 149. 141. 132. 116. 102. 86. 78. 73. 79. + 87. 91. 93. 95. 98. 99. 99. 100. 100. 99. 99. 99. 101. 101. 102. + 103. 105. 108. 110. 111. 112. 115. 118. 120. 119. 118. 119. 120. + 126. 109. 118. 137. 129. 109. 105. 111. 110. 113. 115. 114. 111. + 110. 112. 115. 117. 115. 114. 115. 118. 120. 121. 120. 124. 128. + 130. 129. 126. 127. 132. 137. 140. 140. 140. 139. 139. 138. 138. + 138. 135. 133. 133. 135. 138. 141. 142. 142. 142. 157. 152. 134. + 146. 185. 201. 190. 193. 197. 197. 194. 194. 200. 205. 205. 198. + 198. 198. 198. 199. 199. 199. 199. 199. 199. 201. 202. 204. 205. + 206. 207. 207. 208. 209. 210. 211. 211. 211. 211. 213. 216. 219. + 225. 230. 210. 152. 95. 62. 73. 83. 73. 86. 106. 106. 124. 137. 144. + 152. 156. 155. 154. 153. 155. 151. 154. 155. 151. 145. 133. 115. 99. + 69. 51. 45. 43. 35. 43. 67. 82. 107. 117. 131. 141. 145. 146. 148. + 149. 147. 141. 138. 140. 143. 143. 146. 149. 149. 154. 155. 136. 92. + 49. 35. 41. 40. 41. 44. 49. 54. 56. 56. 54. 58. 56. 52. 46. 44. 47. + 56. 63. 48. 46. 46. 49. 55. 58. 58. 57. 55. 67. 79. 102. 133. 147. + 146. 149. 147. 145. 146. 153. 163. 168. 166. 161. 85. 87. 90. 91. + 91. 91. 91. 92. 93. 90. 87. 89. 99. 114. 130. 141. 149. 156. 162. + 162. 164. 166. 167. 164. 162. 162. 157. 149. 141. 131. 115. 101. 88. + 79. 74. 78. 86. 90. 93. 96. 96. 97. 99. 101. 101. 100. 99. 98. 100. + 101. 101. 103. 105. 107. 109. 111. 113. 115. 117. 119. 120. 119. + 119. 119. 120. 115. 129. 137. 118. 103. 104. 105. 107. 112. 116. + 116. 111. 109. 111. 115. 115. 113. 113. 115. 118. 121. 121. 121. + 131. 132. 133. 133. 132. 135. 140. 144. 140. 140. 141. 141. 140. + 139. 138. 137. 131. 132. 134. 137. 139. 140. 139. 138. 132. 135. + 142. 157. 182. 203. 202. 191. 193. 196. 196. 192. 191. 195. 198. + 198. 197. 197. 198. 198. 198. 198. 198. 198. 202. 203. 204. 205. + 207. 208. 209. 210. 207. 207. 208. 208. 208. 208. 207. 207. 210. + 216. 207. 198. 217. 236. 206. 155. 73. 60. 77. 81. 78. 94. 110. 131. + 136. 143. 151. 155. 155. 153. 154. 155. 152. 155. 155. 151. 144. + 133. 115. 99. 72. 54. 47. 44. 35. 38. 56. 67. 91. 104. 123. 137. + 144. 147. 150. 152. 144. 141. 140. 141. 144. 147. 149. 150. 150. + 157. 146. 105. 61. 38. 39. 45. 41. 44. 48. 52. 55. 56. 54. 53. 57. + 53. 48. 47. 49. 53. 57. 58. 43. 48. 50. 50. 54. 58. 56. 50. 54. 79. + 103. 126. 147. 149. 142. 145. 141. 144. 150. 159. 166. 168. 164. + 159. 84. 87. 91. 93. 92. 91. 91. 92. 94. 91. 89. 91. 100. 116. 132. + 142. 149. 156. 162. 162. 163. 166. 166. 163. 161. 161. 158. 150. + 142. 131. 115. 100. 89. 80. 75. 79. 87. 91. 94. 96. 95. 97. 99. 102. + 102. 101. 99. 97. 99. 99. 100. 101. 104. 106. 108. 109. 113. 114. + 116. 118. 119. 119. 118. 117. 112. 135. 147. 127. 103. 102. 107. + 101. 105. 111. 116. 116. 112. 109. 111. 115. 114. 112. 112. 114. + 118. 120. 121. 121. 134. 132. 132. 134. 139. 143. 144. 144. 136. + 138. 140. 141. 141. 140. 138. 137. 132. 133. 135. 136. 135. 133. + 132. 131. 129. 144. 168. 187. 192. 190. 195. 203. 192. 197. 197. + 193. 190. 191. 191. 189. 193. 193. 195. 197. 199. 201. 202. 203. + 205. 205. 206. 206. 207. 207. 208. 208. 208. 208. 207. 206. 206. + 206. 206. 206. 218. 211. 208. 216. 223. 220. 210. 202. 116. 50. 61. + 84. 72. 91. 117. 124. 135. 142. 150. 155. 155. 153. 154. 155. 152. + 155. 155. 150. 144. 133. 116. 100. 73. 53. 45. 46. 40. 41. 49. 51. + 77. 94. 116. 132. 140. 142. 145. 148. 146. 145. 144. 143. 145. 147. + 147. 145. 154. 156. 127. 73. 40. 41. 48. 45. 44. 47. 51. 54. 56. 55. + 54. 53. 56. 49. 44. 47. 55. 59. 54. 48. 44. 51. 55. 52. 51. 52. 51. + 48. 66. 99. 129. 146. 152. 142. 134. 139. 139. 147. 158. 165. 166. + 164. 162. 162. 86. 89. 91. 92. 92. 91. 91. 92. 94. 91. 88. 90. 100. + 116. 132. 142. 149. 156. 162. 162. 162. 165. 165. 162. 161. 162. + 159. 151. 143. 132. 115. 100. 89. 80. 76. 81. 88. 91. 93. 95. 95. + 96. 99. 101. 102. 101. 100. 98. 98. 99. 99. 101. 103. 105. 108. 109. + 114. 114. 114. 116. 118. 118. 116. 113. 113. 160. 160. 113. 94. 105. + 107. 101. 106. 110. 114. 114. 112. 111. 112. 114. 115. 114. 113. + 115. 118. 121. 122. 122. 131. 130. 130. 135. 142. 144. 142. 138. + 133. 135. 138. 141. 142. 140. 138. 136. 134. 133. 131. 128. 126. + 127. 130. 133. 160. 177. 188. 184. 183. 192. 198. 197. 192. 196. + 197. 192. 189. 189. 188. 186. 187. 189. 192. 196. 201. 205. 208. + 210. 204. 204. 204. 204. 204. 204. 204. 203. 210. 209. 208. 207. + 206. 206. 207. 207. 205. 214. 220. 218. 214. 215. 219. 221. 174. 73. + 54. 73. 72. 96. 116. 112. 134. 141. 150. 154. 154. 153. 154. 155. + 153. 155. 154. 149. 143. 133. 116. 101. 74. 50. 41. 45. 43. 42. 44. + 39. 65. 82. 105. 121. 128. 133. 138. 143. 136. 137. 136. 135. 139. + 146. 148. 146. 155. 139. 98. 52. 34. 44. 49. 43. 47. 50. 54. 55. 55. + 54. 53. 54. 53. 47. 44. 49. 57. 59. 51. 42. 49. 53. 56. 53. 47. 46. + 52. 60. 90. 122. 146. 154. 149. 135. 130. 140. 145. 154. 165. 168. + 165. 162. 163. 166. 90. 90. 90. 91. 92. 92. 91. 90. 92. 89. 86. 89. + 98. 114. 130. 140. 149. 156. 162. 162. 162. 164. 164. 162. 162. 163. + 160. 153. 145. 133. 116. 101. 87. 79. 75. 81. 88. 90. 91. 92. 95. + 96. 98. 100. 101. 101. 100. 100. 99. 100. 100. 102. 104. 106. 108. + 110. 115. 113. 113. 114. 116. 116. 113. 110. 124. 180. 161. 100. 96. + 110. 104. 104. 108. 109. 110. 111. 112. 112. 113. 113. 118. 117. + 116. 118. 121. 123. 124. 123. 127. 130. 135. 139. 141. 139. 135. + 131. 131. 134. 138. 141. 141. 139. 136. 133. 132. 129. 123. 118. + 120. 131. 146. 157. 187. 194. 190. 180. 183. 196. 196. 183. 192. + 195. 194. 188. 186. 188. 190. 189. 190. 191. 194. 198. 201. 205. + 208. 209. 203. 203. 203. 203. 203. 203. 203. 203. 208. 207. 206. + 205. 204. 205. 206. 206. 193. 214. 220. 206. 203. 220. 230. 224. + 213. 134. 81. 61. 71. 94. 103. 118. 133. 140. 149. 154. 154. 153. + 154. 155. 154. 155. 154. 149. 143. 133. 116. 101. 77. 53. 43. 46. + 43. 41. 42. 37. 48. 64. 86. 103. 114. 125. 139. 149. 145. 144. 139. + 134. 137. 147. 152. 151. 146. 105. 62. 43. 41. 41. 42. 46. 51. 53. + 56. 56. 54. 52. 53. 55. 51. 49. 48. 51. 54. 54. 49. 45. 55. 54. 54. + 51. 42. 41. 61. 85. 120. 140. 151. 148. 143. 134. 134. 147. 154. + 159. 164. 165. 162. 161. 162. 164. 93. 91. 90. 90. 92. 92. 91. 89. + 90. 87. 85. 87. 96. 112. 128. 138. 149. 156. 161. 162. 162. 164. + 164. 161. 162. 163. 160. 154. 146. 134. 117. 101. 85. 77. 74. 80. + 87. 89. 89. 89. 96. 97. 98. 99. 100. 101. 101. 101. 101. 101. 102. + 103. 105. 108. 110. 111. 115. 113. 112. 113. 115. 115. 111. 107. + 135. 189. 157. 93. 101. 112. 100. 108. 110. 109. 108. 110. 112. 114. + 113. 112. 121. 120. 119. 120. 123. 125. 125. 125. 125. 133. 142. + 145. 141. 135. 130. 129. 132. 134. 138. 141. 141. 137. 133. 130. + 129. 123. 116. 112. 120. 140. 166. 184. 178. 190. 200. 198. 187. + 180. 181. 187. 192. 193. 191. 185. 183. 188. 193. 194. 197. 197. + 198. 199. 201. 202. 203. 204. 204. 204. 204. 205. 205. 206. 206. + 206. 205. 204. 202. 201. 201. 202. 203. 204. 206. 200. 208. 224. + 226. 214. 213. 224. 226. 191. 119. 59. 69. 85. 91. 136. 133. 140. + 149. 154. 154. 153. 154. 155. 154. 155. 154. 149. 142. 132. 116. + 101. 82. 58. 48. 48. 42. 40. 43. 41. 33. 49. 70. 89. 105. 123. 144. + 160. 179. 174. 161. 146. 143. 149. 153. 151. 134. 75. 35. 42. 50. + 37. 36. 53. 53. 55. 57. 56. 53. 51. 53. 56. 51. 53. 54. 53. 50. 48. + 49. 51. 59. 54. 51. 49. 39. 40. 70. 106. 140. 151. 149. 141. 139. + 136. 140. 154. 160. 159. 158. 158. 159. 159. 159. 158. 92. 92. 91. + 90. 90. 91. 91. 92. 87. 85. 84. 86. 95. 112. 131. 144. 150. 154. + 160. 164. 164. 163. 162. 162. 165. 166. 162. 154. 146. 136. 120. + 105. 90. 76. 75. 84. 87. 92. 96. 91. 93. 94. 97. 99. 101. 102. 103. + 103. 100. 102. 104. 107. 109. 109. 109. 109. 103. 123. 110. 116. + 106. 117. 105. 113. 192. 181. 131. 97. 108. 105. 94. 109. 112. 112. + 109. 107. 108. 112. 114. 112. 114. 118. 122. 123. 122. 122. 125. + 128. 133. 137. 137. 134. 134. 138. 137. 132. 144. 132. 130. 141. + 145. 135. 126. 126. 130. 102. 100. 132. 164. 184. 188. 180. 182. + 192. 196. 189. 182. 184. 187. 188. 182. 178. 177. 184. 194. 201. + 200. 196. 193. 195. 197. 195. 194. 197. 204. 210. 204. 204. 204. + 205. 206. 205. 203. 201. 200. 200. 201. 202. 204. 207. 209. 210. + 204. 207. 209. 210. 209. 212. 217. 221. 223. 218. 195. 58. 67. 84. + 97. 123. 131. 141. 149. 150. 149. 152. 152. 151. 154. 155. 154. 150. + 146. 136. 117. 100. 75. 53. 41. 48. 50. 40. 38. 46. 40. 39. 45. 68. + 115. 176. 208. 205. 216. 218. 203. 183. 186. 196. 174. 137. 85. 48. + 49. 27. 50. 50. 39. 58. 59. 56. 52. 53. 56. 58. 58. 57. 48. 52. 55. + 51. 46. 45. 51. 58. 53. 53. 49. 42. 43. 64. 100. 128. 144. 145. 143. + 140. 138. 142. 152. 160. 161. 161. 161. 160. 160. 159. 159. 159. 92. + 91. 90. 90. 90. 90. 91. 91. 87. 85. 84. 86. 95. 111. 130. 143. 150. + 154. 160. 164. 164. 163. 162. 162. 165. 165. 161. 153. 145. 135. + 119. 104. 88. 74. 74. 82. 85. 90. 95. 90. 93. 94. 95. 97. 99. 100. + 100. 100. 100. 101. 104. 106. 108. 108. 108. 108. 106. 119. 111. + 113. 106. 113. 101. 133. 199. 180. 127. 95. 109. 110. 100. 110. 107. + 108. 112. 116. 117. 114. 110. 108. 114. 115. 118. 120. 122. 126. + 131. 135. 135. 127. 133. 148. 146. 130. 127. 138. 124. 143. 150. + 136. 121. 119. 121. 118. 117. 121. 138. 154. 163. 179. 192. 189. + 183. 182. 180. 183. 192. 197. 188. 174. 177. 177. 179. 184. 189. + 194. 195. 196. 199. 197. 195. 194. 196. 198. 200. 201. 206. 204. + 201. 200. 200. 200. 200. 200. 202. 202. 202. 203. 205. 207. 209. + 210. 207. 209. 211. 211. 210. 212. 217. 221. 227. 224. 205. 97. 52. + 77. 104. 115. 133. 143. 151. 152. 152. 154. 155. 154. 152. 154. 153. + 149. 145. 135. 117. 99. 74. 59. 49. 49. 48. 42. 37. 37. 33. 38. 59. + 121. 191. 209. 205. 219. 192. 201. 202. 201. 212. 220. 201. 171. 62. + 32. 53. 37. 49. 51. 43. 52. 58. 56. 53. 54. 56. 57. 56. 54. 51. 52. + 53. 50. 47. 48. 53. 58. 53. 49. 45. 47. 61. 89. 123. 147. 149. 145. + 139. 138. 143. 151. 158. 162. 161. 161. 160. 160. 160. 159. 159. + 159. 91. 90. 89. 89. 89. 90. 90. 91. 88. 86. 84. 85. 94. 110. 128. + 141. 150. 154. 160. 164. 165. 164. 163. 163. 164. 164. 160. 152. + 144. 133. 117. 103. 85. 71. 72. 80. 81. 87. 93. 89. 93. 93. 95. 96. + 97. 97. 97. 97. 99. 100. 102. 104. 106. 107. 107. 107. 109. 112. + 112. 108. 107. 107. 99. 165. 198. 172. 118. 90. 104. 108. 100. 107. + 108. 107. 111. 120. 121. 113. 109. 111. 117. 116. 116. 118. 124. + 130. 134. 136. 138. 130. 134. 145. 141. 127. 127. 139. 132. 142. + 140. 124. 114. 116. 116. 109. 121. 145. 173. 177. 170. 181. 194. + 189. 181. 175. 170. 175. 188. 196. 188. 175. 180. 183. 187. 190. + 190. 192. 196. 200. 201. 197. 193. 194. 197. 199. 197. 194. 201. + 200. 197. 195. 196. 198. 201. 203. 204. 204. 204. 204. 205. 206. + 208. 208. 208. 209. 209. 209. 209. 210. 213. 216. 226. 227. 217. + 150. 53. 67. 106. 110. 132. 142. 150. 152. 153. 155. 156. 154. 152. + 153. 152. 149. 144. 135. 116. 99. 76. 59. 43. 40. 44. 44. 40. 36. + 38. 51. 130. 211. 224. 216. 211. 195. 196. 205. 213. 220. 229. 232. + 218. 200. 68. 25. 55. 45. 43. 48. 51. 51. 57. 56. 55. 55. 56. 55. + 53. 51. 54. 52. 50. 49. 49. 51. 54. 57. 50. 42. 38. 51. 80. 115. + 142. 155. 152. 143. 136. 139. 151. 161. 165. 163. 161. 160. 160. + 160. 159. 159. 159. 159. 90. 89. 89. 89. 89. 90. 91. 91. 89. 87. 85. + 85. 93. 109. 127. 139. 150. 154. 160. 164. 165. 164. 164. 164. 163. + 163. 159. 151. 143. 132. 116. 101. 82. 69. 70. 77. 78. 84. 91. 89. + 94. 95. 96. 97. 97. 97. 96. 96. 99. 99. 101. 103. 104. 106. 106. + 107. 112. 108. 113. 105. 107. 103. 107. 195. 192. 163. 116. 92. 101. + 104. 100. 106. 115. 108. 109. 117. 116. 109. 111. 120. 121. 119. + 118. 122. 127. 131. 131. 130. 137. 140. 135. 123. 123. 134. 137. + 132. 147. 131. 120. 120. 117. 111. 116. 129. 152. 163. 181. 184. + 177. 182. 187. 179. 177. 177. 175. 171. 170. 176. 184. 190. 185. + 187. 190. 192. 192. 194. 196. 199. 197. 195. 193. 194. 196. 197. + 195. 192. 194. 194. 195. 196. 198. 201. 206. 209. 204. 204. 203. + 203. 203. 204. 205. 206. 206. 206. 206. 205. 205. 206. 208. 209. + 218. 227. 225. 189. 92. 62. 96. 113. 128. 138. 148. 150. 151. 153. + 154. 152. 153. 154. 153. 149. 145. 135. 116. 99. 73. 53. 40. 42. 45. + 39. 36. 40. 76. 160. 208. 213. 216. 198. 184. 204. 220. 221. 223. + 226. 228. 228. 224. 220. 121. 35. 49. 47. 40. 44. 56. 56. 56. 56. + 56. 56. 55. 53. 50. 48. 56. 52. 48. 48. 51. 54. 56. 55. 49. 41. 42. + 65. 103. 136. 150. 151. 146. 141. 139. 146. 157. 165. 166. 164. 160. + 160. 160. 159. 159. 159. 158. 158. 90. 89. 89. 89. 90. 90. 92. 92. + 91. 89. 86. 86. 93. 108. 126. 138. 149. 154. 161. 165. 166. 165. + 165. 165. 164. 164. 159. 151. 142. 131. 115. 100. 81. 68. 69. 76. + 76. 82. 91. 90. 97. 97. 98. 99. 99. 98. 98. 97. 99. 99. 100. 102. + 103. 105. 106. 107. 113. 107. 114. 104. 107. 101. 127. 212. 187. + 159. 122. 103. 104. 104. 105. 111. 113. 109. 110. 116. 114. 109. + 112. 121. 120. 120. 122. 127. 131. 132. 128. 124. 131. 132. 125. + 115. 122. 138. 140. 130. 132. 126. 122. 118. 108. 108. 132. 164. + 182. 173. 178. 184. 175. 170. 174. 175. 174. 177. 179. 173. 166. + 167. 179. 191. 187. 186. 185. 187. 190. 191. 191. 190. 194. 196. + 197. 195. 192. 189. 190. 192. 191. 195. 199. 201. 202. 204. 207. + 209. 203. 202. 201. 201. 201. 202. 202. 203. 207. 206. 204. 203. + 204. 205. 206. 206. 212. 226. 228. 206. 153. 74. 77. 113. 126. 137. + 147. 151. 152. 154. 155. 153. 155. 156. 154. 150. 145. 134. 115. 97. + 66. 49. 43. 47. 37. 28. 52. 90. 186. 203. 226. 200. 159. 186. 225. + 213. 222. 221. 221. 222. 223. 225. 230. 236. 180. 48. 38. 46. 45. + 44. 55. 56. 54. 55. 56. 55. 53. 50. 48. 47. 54. 50. 47. 48. 52. 56. + 55. 53. 49. 49. 61. 91. 129. 152. 154. 146. 137. 141. 147. 154. 159. + 162. 163. 162. 160. 160. 159. 159. 159. 158. 158. 158. 90. 90. 90. + 90. 91. 92. 93. 94. 94. 91. 88. 88. 94. 108. 125. 137. 149. 154. + 161. 165. 166. 166. 166. 166. 164. 164. 160. 151. 142. 131. 115. + 100. 80. 69. 70. 77. 76. 82. 92. 92. 98. 98. 99. 100. 100. 100. 100. + 99. 100. 100. 100. 101. 103. 105. 107. 108. 111. 110. 114. 107. 107. + 103. 157. 215. 180. 149. 118. 104. 100. 100. 104. 109. 104. 109. + 115. 117. 115. 113. 113. 114. 116. 119. 124. 130. 132. 131. 126. + 122. 123. 114. 115. 128. 137. 135. 131. 132. 119. 122. 116. 107. + 115. 141. 162. 167. 187. 175. 178. 181. 165. 156. 166. 177. 175. + 174. 175. 179. 179. 176. 175. 176. 191. 189. 187. 188. 190. 191. + 190. 187. 195. 197. 198. 194. 188. 185. 187. 191. 195. 199. 203. + 204. 202. 201. 202. 204. 201. 200. 200. 200. 200. 201. 201. 202. + 210. 207. 205. 205. 206. 207. 208. 207. 210. 224. 225. 213. 200. + 114. 70. 107. 127. 138. 149. 153. 155. 157. 158. 155. 157. 157. 155. + 150. 143. 132. 112. 94. 63. 46. 34. 31. 29. 53. 121. 192. 214. 213. + 180. 166. 198. 213. 211. 226. 213. 216. 218. 218. 219. 223. 229. + 234. 209. 60. 35. 44. 52. 48. 50. 50. 53. 54. 55. 53. 50. 48. 48. + 48. 50. 48. 47. 49. 53. 55. 54. 51. 45. 58. 83. 117. 145. 156. 151. + 142. 135. 144. 155. 160. 159. 158. 158. 160. 159. 159. 159. 159. + 158. 158. 158. 157. 91. 91. 91. 91. 92. 93. 95. 95. 96. 93. 90. 89. + 95. 109. 125. 137. 149. 154. 161. 165. 167. 166. 166. 166. 165. 165. + 161. 152. 143. 132. 115. 100. 81. 70. 72. 78. 77. 83. 94. 95. 97. + 98. 99. 100. 101. 101. 101. 100. 101. 101. 101. 101. 103. 105. 108. + 109. 109. 115. 114. 112. 108. 106. 187. 208. 178. 139. 107. 97. 94. + 96. 102. 103. 100. 112. 117. 111. 109. 114. 116. 113. 119. 123. 128. + 130. 129. 125. 122. 120. 119. 118. 124. 133. 135. 128. 125. 128. + 118. 114. 107. 114. 144. 175. 179. 165. 177. 170. 172. 172. 161. + 162. 171. 172. 176. 173. 175. 183. 186. 181. 175. 175. 191. 193. + 193. 192. 189. 188. 189. 190. 191. 191. 190. 188. 188. 189. 192. + 194. 196. 199. 202. 200. 196. 195. 198. 202. 200. 200. 200. 200. + 200. 202. 203. 203. 210. 207. 204. 204. 207. 208. 208. 207. 207. + 216. 216. 217. 216. 173. 87. 102. 125. 137. 149. 154. 156. 158. 158. + 156. 157. 157. 154. 148. 140. 128. 107. 89. 57. 41. 27. 37. 76. 135. + 194. 231. 196. 166. 172. 203. 216. 222. 219. 203. 210. 216. 216. + 210. 210. 219. 226. 227. 216. 79. 45. 38. 48. 49. 49. 47. 52. 53. + 54. 51. 48. 47. 48. 50. 45. 46. 48. 51. 53. 53. 52. 50. 47. 72. 109. + 139. 152. 152. 145. 139. 142. 149. 158. 160. 158. 156. 157. 159. + 159. 159. 159. 158. 158. 158. 157. 157. 92. 91. 91. 92. 93. 94. 96. + 96. 98. 95. 91. 90. 96. 109. 126. 137. 149. 154. 161. 165. 167. 167. + 167. 167. 166. 166. 161. 152. 143. 132. 115. 100. 82. 71. 73. 79. + 77. 84. 95. 97. 96. 97. 98. 100. 100. 101. 101. 101. 102. 101. 101. + 102. 103. 106. 108. 110. 107. 118. 114. 115. 108. 109. 206. 201. + 184. 137. 102. 94. 93. 99. 106. 103. 104. 116. 116. 101. 98. 112. + 121. 118. 126. 129. 132. 129. 124. 119. 117. 117. 119. 138. 142. + 126. 117. 125. 128. 119. 113. 107. 116. 143. 166. 173. 177. 184. + 171. 165. 163. 161. 165. 180. 181. 161. 175. 176. 180. 184. 180. + 174. 178. 187. 185. 190. 194. 190. 183. 180. 183. 188. 186. 183. + 180. 183. 190. 197. 200. 200. 193. 196. 197. 195. 191. 192. 198. + 204. 201. 200. 200. 201. 202. 203. 204. 205. 208. 204. 201. 202. + 205. 207. 207. 205. 203. 206. 206. 221. 213. 220. 111. 101. 122. + 135. 147. 152. 154. 156. 156. 154. 156. 156. 153. 146. 138. 125. + 104. 85. 45. 38. 39. 78. 156. 219. 217. 182. 164. 179. 198. 216. + 223. 212. 206. 215. 209. 214. 209. 198. 201. 218. 231. 232. 218. 98. + 59. 32. 38. 47. 50. 49. 52. 53. 53. 50. 46. 46. 48. 52. 41. 44. 49. + 52. 53. 52. 50. 49. 59. 91. 132. 157. 160. 151. 144. 142. 150. 154. + 158. 159. 157. 156. 157. 158. 159. 159. 159. 158. 158. 157. 157. + 157. 94. 95. 95. 96. 97. 98. 99. 99. 100. 97. 94. 94. 100. 113. 128. + 139. 148. 154. 162. 168. 170. 169. 167. 167. 166. 167. 164. 156. + 147. 135. 117. 101. 84. 77. 73. 77. 84. 88. 92. 96. 97. 98. 98. 99. + 100. 101. 102. 102. 97. 99. 102. 105. 107. 108. 108. 108. 116. 108. + 116. 102. 100. 126. 212. 198. 177. 141. 108. 99. 103. 104. 106. 110. + 111. 101. 95. 101. 111. 116. 117. 118. 127. 122. 121. 122. 120. 115. + 117. 123. 133. 134. 130. 127. 130. 133. 126. 115. 102. 132. 155. + 158. 163. 178. 181. 171. 170. 158. 156. 168. 175. 172. 170. 174. + 182. 185. 178. 168. 173. 189. 192. 183. 183. 185. 188. 189. 189. + 187. 186. 185. 167. 173. 182. 190. 195. 198. 199. 199. 197. 189. + 194. 207. 206. 191. 186. 194. 204. 201. 199. 201. 205. 206. 204. + 202. 195. 193. 195. 201. 203. 202. 203. 206. 202. 209. 208. 205. + 214. 215. 178. 132. 120. 132. 145. 151. 151. 152. 154. 155. 167. + 154. 144. 141. 136. 119. 97. 82. 46. 67. 118. 183. 221. 213. 183. + 162. 194. 203. 209. 211. 213. 216. 213. 206. 198. 199. 202. 206. + 212. 219. 224. 227. 218. 98. 39. 37. 57. 46. 57. 58. 53. 48. 43. 42. + 45. 46. 46. 44. 46. 49. 51. 51. 47. 43. 42. 44. 68. 117. 152. 157. + 152. 144. 142. 149. 161. 161. 160. 160. 159. 158. 157. 157. 157. + 157. 157. 156. 156. 155. 155. 155. 95. 96. 96. 97. 98. 99. 100. 100. + 99. 97. 94. 94. 100. 112. 128. 139. 148. 154. 162. 167. 169. 168. + 167. 166. 166. 167. 163. 156. 147. 135. 117. 102. 85. 78. 74. 79. + 85. 89. 93. 97. 98. 99. 99. 100. 101. 102. 102. 103. 99. 100. 103. + 105. 108. 109. 109. 109. 115. 113. 115. 105. 100. 142. 216. 200. + 167. 136. 106. 98. 100. 101. 103. 108. 96. 97. 105. 116. 122. 123. + 123. 126. 124. 121. 120. 122. 121. 119. 122. 129. 131. 130. 134. + 138. 132. 118. 110. 109. 132. 140. 157. 171. 171. 161. 157. 160. + 158. 177. 180. 159. 152. 169. 183. 183. 176. 182. 182. 175. 175. + 183. 188. 187. 181. 180. 181. 186. 189. 186. 175. 165. 179. 183. + 187. 187. 185. 187. 194. 201. 208. 196. 190. 193. 194. 192. 197. + 206. 198. 200. 200. 197. 193. 190. 190. 192. 198. 196. 198. 202. + 204. 201. 201. 204. 204. 207. 204. 202. 213. 223. 212. 190. 153. + 141. 137. 146. 153. 153. 154. 159. 151. 150. 151. 150. 136. 108. 80. + 64. 106. 153. 200. 210. 190. 177. 188. 205. 207. 212. 214. 211. 209. + 210. 206. 199. 200. 201. 204. 208. 213. 219. 224. 227. 219. 88. 44. + 40. 51. 45. 53. 59. 54. 51. 47. 45. 45. 46. 47. 47. 49. 51. 54. 53. + 44. 37. 43. 55. 92. 130. 154. 152. 148. 144. 145. 154. 161. 160. + 160. 159. 158. 157. 157. 156. 157. 157. 156. 156. 156. 155. 155. + 155. 97. 97. 98. 99. 99. 100. 100. 101. 98. 96. 94. 94. 100. 112. + 127. 138. 147. 153. 161. 166. 168. 167. 167. 167. 165. 166. 164. + 156. 148. 137. 119. 103. 86. 79. 76. 81. 87. 91. 94. 98. 100. 100. + 100. 101. 102. 103. 103. 103. 100. 101. 103. 106. 108. 109. 110. + 110. 112. 120. 111. 108. 98. 165. 217. 198. 152. 128. 105. 97. 96. + 96. 100. 106. 98. 104. 114. 121. 118. 112. 112. 118. 116. 115. 117. + 120. 121. 121. 124. 130. 130. 125. 129. 137. 126. 106. 106. 121. + 156. 154. 159. 166. 163. 152. 149. 153. 171. 166. 163. 164. 165. + 169. 177. 186. 174. 181. 186. 183. 177. 175. 181. 187. 181. 180. + 180. 180. 179. 175. 169. 164. 182. 187. 191. 188. 182. 182. 189. + 198. 199. 196. 193. 194. 197. 199. 198. 196. 190. 202. 207. 192. + 170. 164. 180. 200. 201. 199. 200. 204. 204. 200. 200. 203. 205. + 204. 200. 197. 203. 213. 218. 218. 203. 167. 141. 145. 154. 152. + 149. 152. 148. 152. 152. 138. 114. 101. 111. 129. 185. 211. 221. + 200. 177. 180. 200. 215. 215. 217. 214. 208. 205. 204. 201. 197. + 203. 204. 206. 210. 215. 219. 223. 226. 220. 71. 48. 44. 45. 46. 48. + 57. 55. 54. 52. 49. 46. 46. 47. 50. 52. 52. 55. 52. 38. 30. 49. 76. + 123. 147. 154. 146. 144. 145. 149. 160. 160. 159. 159. 158. 157. + 156. 156. 155. 157. 156. 156. 156. 155. 155. 155. 155. 99. 99. 99. + 100. 100. 101. 101. 101. 98. 96. 94. 94. 100. 112. 127. 137. 147. + 152. 160. 165. 167. 167. 167. 167. 166. 167. 164. 157. 149. 138. + 120. 104. 86. 79. 76. 81. 88. 91. 94. 98. 101. 101. 101. 102. 102. + 103. 103. 103. 99. 100. 102. 104. 106. 108. 109. 110. 109. 125. 106. + 107. 98. 186. 212. 189. 139. 123. 107. 99. 95. 94. 99. 105. 111. + 111. 113. 112. 106. 102. 107. 116. 112. 115. 120. 124. 125. 125. + 125. 127. 128. 121. 117. 118. 113. 110. 126. 148. 157. 163. 159. + 146. 145. 156. 160. 153. 164. 152. 155. 173. 181. 172. 169. 177. + 178. 180. 184. 184. 178. 171. 175. 184. 182. 185. 184. 174. 164. + 163. 175. 187. 175. 182. 189. 191. 188. 186. 188. 190. 190. 195. + 196. 195. 199. 204. 199. 187. 201. 199. 190. 176. 166. 170. 188. + 204. 201. 199. 200. 203. 204. 200. 200. 202. 200. 196. 195. 198. + 199. 199. 204. 209. 225. 191. 157. 147. 154. 157. 152. 147. 156. + 147. 135. 126. 127. 145. 180. 210. 217. 203. 184. 177. 191. 210. + 213. 205. 212. 211. 207. 203. 201. 202. 202. 202. 206. 207. 209. + 213. 216. 220. 223. 224. 214. 54. 48. 45. 42. 51. 45. 51. 54. 55. + 54. 50. 45. 44. 47. 51. 54. 52. 52. 48. 33. 31. 63. 104. 145. 157. + 152. 142. 144. 148. 153. 163. 159. 159. 158. 157. 156. 156. 155. + 155. 156. 156. 156. 155. 155. 155. 154. 154. 100. 100. 100. 100. + 100. 101. 101. 101. 98. 97. 95. 96. 102. 114. 128. 138. 147. 153. + 160. 165. 167. 168. 168. 169. 167. 168. 165. 158. 150. 138. 120. + 105. 84. 78. 75. 81. 87. 90. 93. 96. 101. 102. 102. 102. 102. 103. + 103. 103. 98. 99. 100. 102. 104. 106. 108. 109. 107. 123. 101. 103. + 101. 200. 203. 175. 135. 124. 111. 103. 98. 96. 101. 106. 110. 106. + 103. 105. 107. 110. 117. 125. 113. 120. 127. 130. 130. 129. 126. + 124. 122. 119. 112. 106. 111. 129. 149. 162. 153. 158. 154. 143. + 142. 153. 157. 152. 135. 162. 179. 172. 167. 175. 179. 173. 179. + 175. 174. 177. 177. 175. 177. 182. 181. 180. 176. 169. 165. 170. + 183. 195. 178. 179. 182. 185. 188. 189. 187. 185. 191. 195. 192. + 185. 190. 203. 207. 200. 207. 185. 164. 165. 183. 199. 198. 191. + 198. 196. 197. 201. 202. 199. 199. 202. 195. 191. 193. 200. 203. + 200. 201. 205. 210. 200. 176. 151. 149. 160. 159. 146. 149. 136. + 134. 157. 188. 207. 210. 207. 196. 184. 180. 194. 209. 214. 212. + 212. 205. 203. 201. 200. 200. 201. 204. 206. 207. 208. 211. 214. + 218. 220. 222. 223. 195. 43. 45. 45. 45. 57. 46. 46. 52. 53. 52. 48. + 44. 43. 46. 50. 54. 51. 49. 45. 36. 45. 86. 130. 152. 157. 149. 142. + 148. 152. 155. 164. 159. 159. 158. 157. 156. 156. 155. 155. 156. + 156. 155. 155. 155. 154. 154. 154. 100. 100. 100. 100. 100. 100. + 100. 100. 99. 98. 97. 98. 104. 115. 129. 139. 149. 153. 160. 165. + 168. 169. 170. 171. 169. 170. 167. 159. 150. 138. 120. 104. 83. 77. + 75. 81. 88. 90. 92. 95. 101. 101. 101. 101. 102. 102. 102. 102. 98. + 98. 99. 100. 102. 105. 107. 108. 105. 117. 97. 99. 112. 210. 196. + 164. 136. 128. 117. 107. 101. 100. 103. 106. 103. 98. 97. 104. 110. + 112. 114. 116. 111. 118. 125. 125. 124. 123. 120. 116. 116. 120. + 119. 117. 127. 145. 156. 156. 155. 146. 147. 157. 153. 139. 138. + 150. 153. 161. 168. 171. 174. 178. 179. 177. 172. 168. 166. 169. + 177. 182. 182. 180. 173. 168. 164. 169. 178. 185. 183. 179. 188. + 182. 176. 175. 180. 184. 184. 183. 180. 188. 191. 190. 194. 201. + 203. 199. 179. 177. 176. 180. 188. 193. 193. 191. 196. 193. 195. + 199. 199. 196. 196. 199. 199. 195. 193. 195. 197. 196. 196. 198. + 197. 209. 196. 159. 142. 151. 153. 142. 140. 152. 177. 202. 212. + 205. 191. 183. 184. 185. 198. 215. 216. 204. 201. 209. 203. 200. + 199. 201. 201. 200. 202. 205. 207. 208. 211. 215. 218. 221. 222. + 223. 162. 41. 44. 46. 51. 57. 50. 44. 51. 50. 48. 46. 44. 44. 46. + 49. 53. 52. 50. 47. 51. 72. 112. 146. 150. 153. 147. 144. 153. 156. + 156. 163. 160. 159. 159. 158. 157. 156. 156. 155. 155. 155. 155. + 155. 154. 154. 154. 153. 100. 100. 100. 99. 99. 99. 99. 99. 100. 99. + 99. 100. 106. 117. 130. 140. 150. 155. 161. 166. 168. 170. 172. 173. + 172. 172. 168. 160. 150. 138. 119. 103. 84. 78. 77. 83. 89. 92. 94. + 96. 101. 101. 101. 101. 100. 100. 100. 100. 99. 99. 99. 100. 103. + 105. 108. 109. 106. 110. 97. 97. 128. 218. 195. 161. 141. 133. 120. + 109. 104. 104. 105. 106. 104. 99. 99. 104. 107. 106. 104. 106. 112. + 118. 120. 116. 115. 118. 118. 115. 114. 118. 128. 139. 146. 149. + 149. 149. 152. 143. 146. 156. 150. 136. 138. 154. 178. 155. 149. + 171. 186. 178. 170. 173. 164. 167. 167. 167. 174. 184. 181. 172. + 161. 163. 169. 176. 181. 181. 177. 172. 186. 182. 177. 174. 175. + 178. 180. 181. 174. 182. 191. 193. 190. 187. 184. 183. 166. 180. + 193. 192. 182. 177. 184. 194. 195. 193. 193. 196. 196. 192. 191. + 193. 195. 197. 196. 191. 187. 187. 187. 187. 194. 211. 205. 170. + 142. 143. 152. 155. 165. 185. 207. 212. 196. 179. 181. 191. 197. + 199. 205. 210. 210. 204. 199. 197. 203. 200. 201. 205. 205. 201. + 201. 204. 205. 207. 211. 215. 218. 221. 222. 223. 124. 45. 46. 49. + 55. 51. 55. 48. 51. 48. 45. 44. 45. 47. 48. 49. 52. 55. 55. 56. 72. + 102. 134. 151. 147. 150. 146. 147. 157. 159. 157. 164. 161. 160. + 160. 159. 158. 157. 157. 156. 155. 155. 155. 154. 154. 154. 153. + 153. 99. 99. 99. 99. 99. 99. 99. 99. 101. 100. 100. 101. 107. 118. + 131. 140. 151. 155. 161. 166. 169. 171. 173. 175. 173. 173. 169. + 161. 151. 137. 118. 102. 85. 80. 78. 85. 91. 93. 95. 97. 100. 100. + 100. 100. 100. 100. 100. 99. 100. 100. 100. 101. 103. 106. 109. 111. + 106. 105. 97. 97. 139. 223. 197. 162. 144. 136. 122. 110. 105. 106. + 106. 104. 108. 104. 102. 105. 106. 106. 110. 116. 120. 124. 123. + 116. 115. 121. 125. 124. 117. 116. 131. 153. 157. 145. 142. 150. + 143. 149. 148. 139. 135. 143. 155. 163. 157. 168. 172. 168. 170. + 176. 172. 161. 161. 171. 174. 169. 172. 181. 176. 162. 151. 168. + 184. 184. 173. 166. 171. 180. 174. 177. 180. 180. 178. 176. 177. + 178. 189. 187. 184. 177. 168. 163. 169. 179. 190. 185. 180. 181. + 185. 187. 184. 180. 196. 193. 192. 195. 193. 188. 187. 189. 179. + 191. 198. 193. 187. 188. 189. 187. 186. 200. 200. 176. 150. 147. + 166. 184. 205. 200. 197. 196. 193. 191. 193. 198. 206. 213. 212. + 201. 198. 205. 207. 201. 202. 199. 202. 209. 209. 204. 202. 205. + 204. 207. 210. 215. 218. 221. 222. 222. 99. 50. 49. 52. 57. 45. 57. + 52. 52. 48. 44. 44. 47. 50. 50. 49. 52. 58. 60. 64. 87. 123. 146. + 150. 146. 150. 146. 149. 159. 160. 157. 164. 161. 161. 160. 160. + 159. 158. 157. 157. 155. 155. 155. 154. 154. 153. 153. 153. 100. + 100. 100. 99. 99. 98. 98. 98. 100. 101. 100. 100. 104. 114. 129. + 140. 150. 158. 165. 168. 170. 173. 173. 171. 172. 173. 171. 163. + 153. 139. 119. 102. 84. 78. 77. 84. 92. 94. 94. 94. 94. 97. 101. + 102. 101. 99. 99. 99. 96. 97. 98. 100. 102. 104. 105. 106. 104. 101. + 96. 86. 190. 209. 189. 166. 148. 139. 125. 112. 104. 103. 105. 107. + 106. 103. 103. 108. 112. 111. 110. 111. 122. 116. 113. 120. 125. + 124. 120. 119. 114. 129. 144. 151. 153. 152. 143. 133. 147. 148. + 138. 128. 139. 161. 164. 151. 154. 164. 165. 156. 153. 163. 170. + 169. 179. 171. 172. 178. 175. 161. 153. 156. 178. 174. 171. 174. + 179. 181. 178. 173. 176. 175. 173. 173. 175. 178. 182. 185. 193. + 190. 181. 173. 173. 181. 186. 187. 192. 184. 177. 180. 189. 195. + 192. 186. 191. 193. 194. 192. 189. 186. 185. 185. 191. 185. 186. + 194. 193. 184. 182. 188. 180. 189. 194. 187. 175. 177. 195. 214. + 198. 190. 183. 185. 195. 204. 209. 209. 206. 205. 203. 202. 201. + 200. 200. 200. 196. 205. 208. 201. 199. 204. 205. 200. 190. 218. + 215. 204. 225. 228. 214. 219. 72. 55. 43. 47. 55. 55. 52. 51. 53. + 50. 46. 45. 45. 47. 48. 49. 57. 57. 62. 79. 109. 137. 150. 149. 142. + 144. 149. 153. 157. 158. 159. 159. 160. 159. 158. 157. 157. 157. + 157. 158. 155. 155. 155. 155. 155. 155. 155. 155. 100. 100. 99. 99. + 99. 98. 98. 98. 100. 100. 100. 100. 104. 114. 129. 140. 149. 158. + 165. 168. 170. 174. 174. 172. 173. 173. 170. 162. 152. 139. 120. + 103. 85. 77. 74. 80. 88. 92. 93. 95. 95. 97. 101. 102. 101. 99. 99. + 99. 97. 97. 99. 100. 102. 103. 105. 105. 102. 98. 93. 92. 197. 209. + 191. 171. 148. 139. 126. 113. 106. 103. 103. 104. 104. 102. 105. + 111. 114. 113. 114. 117. 126. 119. 116. 122. 128. 125. 119. 115. + 132. 140. 151. 156. 148. 139. 141. 151. 142. 133. 131. 140. 147. + 148. 152. 158. 167. 163. 159. 156. 155. 156. 164. 172. 180. 176. + 173. 170. 160. 152. 163. 182. 178. 175. 172. 172. 175. 177. 176. + 174. 171. 170. 170. 171. 175. 180. 186. 189. 183. 184. 182. 178. + 179. 183. 184. 181. 190. 187. 185. 185. 188. 192. 193. 193. 189. + 189. 189. 186. 183. 182. 183. 184. 190. 185. 184. 185. 179. 172. + 178. 192. 181. 182. 186. 192. 197. 200. 199. 197. 194. 192. 192. + 196. 202. 205. 204. 202. 205. 204. 203. 201. 200. 200. 200. 200. + 201. 205. 207. 204. 203. 203. 200. 195. 200. 213. 212. 207. 221. + 219. 221. 205. 50. 43. 39. 44. 47. 46. 46. 49. 53. 49. 45. 44. 48. + 52. 54. 54. 60. 65. 77. 98. 128. 150. 155. 149. 145. 148. 153. 158. + 161. 162. 161. 161. 160. 159. 158. 157. 157. 157. 157. 158. 155. + 155. 155. 155. 155. 155. 155. 155. 100. 99. 99. 99. 98. 98. 98. 98. + 99. 100. 100. 100. 104. 114. 129. 140. 149. 157. 165. 168. 170. 174. + 175. 173. 174. 174. 169. 161. 151. 139. 120. 105. 85. 76. 71. 76. + 84. 89. 92. 95. 95. 98. 101. 101. 100. 99. 99. 100. 97. 98. 99. 100. + 102. 103. 104. 105. 102. 95. 90. 103. 207. 208. 192. 177. 150. 143. + 132. 122. 116. 113. 111. 109. 104. 103. 107. 112. 113. 111. 112. + 117. 123. 122. 124. 127. 124. 118. 118. 123. 146. 152. 152. 144. + 139. 142. 147. 149. 132. 130. 136. 147. 151. 147. 149. 155. 165. + 153. 151. 161. 165. 160. 164. 175. 177. 170. 165. 162. 157. 157. + 171. 189. 175. 174. 173. 173. 173. 173. 174. 174. 174. 172. 170. + 170. 173. 177. 183. 186. 175. 181. 184. 183. 183. 183. 180. 174. + 184. 187. 190. 189. 186. 186. 191. 196. 187. 185. 183. 179. 176. + 177. 180. 184. 185. 177. 176. 183. 185. 176. 168. 166. 177. 186. + 196. 199. 196. 193. 193. 196. 192. 196. 203. 208. 209. 205. 200. + 195. 203. 202. 201. 200. 199. 199. 199. 200. 204. 203. 205. 207. + 205. 197. 192. 191. 205. 203. 209. 212. 220. 211. 224. 165. 36. 38. + 43. 48. 47. 45. 49. 56. 50. 44. 40. 41. 48. 53. 54. 53. 50. 66. 89. + 117. 142. 156. 152. 141. 147. 151. 156. 161. 163. 163. 162. 160. + 160. 159. 158. 157. 157. 157. 157. 158. 155. 155. 155. 155. 155. + 155. 155. 155. 99. 99. 99. 98. 98. 98. 97. 97. 98. 99. 99. 99. 103. + 114. 129. 140. 149. 157. 165. 168. 171. 175. 176. 174. 174. 174. + 169. 159. 150. 138. 121. 106. 85. 76. 72. 78. 86. 90. 92. 94. 96. + 98. 100. 101. 100. 99. 99. 100. 98. 98. 99. 100. 102. 103. 104. 104. + 103. 96. 89. 113. 217. 204. 191. 178. 150. 144. 136. 129. 126. 122. + 118. 115. 106. 105. 107. 110. 108. 104. 106. 111. 117. 122. 127. + 124. 115. 112. 124. 140. 148. 154. 144. 128. 135. 155. 149. 125. + 128. 145. 153. 148. 150. 159. 155. 140. 144. 141. 148. 165. 176. + 175. 172. 173. 166. 156. 153. 163. 173. 174. 171. 170. 169. 172. + 175. 175. 174. 173. 174. 174. 180. 177. 173. 170. 169. 171. 173. + 175. 176. 181. 184. 182. 180. 180. 178. 173. 177. 183. 188. 189. + 186. 184. 185. 188. 186. 184. 180. 175. 173. 174. 179. 183. 183. + 177. 174. 177. 177. 171. 166. 165. 187. 193. 196. 190. 182. 181. + 189. 198. 196. 202. 209. 211. 208. 202. 197. 195. 201. 201. 200. + 199. 199. 199. 200. 200. 202. 201. 204. 207. 198. 183. 181. 188. + 203. 196. 208. 214. 220. 214. 218. 108. 35. 40. 47. 50. 48. 49. 54. + 60. 50. 45. 42. 44. 51. 55. 53. 49. 38. 66. 104. 133. 149. 153. 146. + 137. 148. 151. 156. 161. 163. 162. 160. 158. 160. 159. 158. 157. + 157. 157. 157. 158. 156. 156. 156. 156. 156. 156. 156. 156. 99. 99. + 98. 98. 98. 97. 97. 97. 97. 98. 98. 99. 103. 114. 129. 140. 150. + 158. 166. 168. 171. 175. 176. 173. 173. 173. 168. 159. 150. 139. + 122. 107. 83. 77. 75. 82. 90. 93. 93. 93. 96. 98. 100. 100. 99. 98. + 99. 101. 98. 99. 99. 100. 102. 103. 103. 104. 104. 99. 89. 121. 222. + 199. 189. 175. 151. 145. 137. 131. 128. 123. 116. 110. 108. 105. + 105. 107. 106. 104. 106. 111. 121. 115. 111. 113. 118. 125. 136. + 147. 147. 146. 140. 135. 140. 144. 134. 117. 139. 152. 156. 150. + 153. 161. 151. 132. 138. 145. 152. 159. 172. 181. 176. 165. 154. + 152. 158. 171. 182. 180. 169. 160. 163. 168. 174. 178. 178. 176. + 174. 173. 175. 173. 170. 168. 168. 169. 171. 172. 175. 179. 180. + 176. 175. 179. 182. 183. 177. 180. 184. 188. 189. 187. 181. 177. + 184. 183. 180. 177. 174. 174. 177. 180. 186. 181. 173. 162. 155. + 161. 180. 200. 200. 189. 177. 177. 186. 195. 197. 196. 201. 205. + 208. 206. 201. 198. 198. 200. 200. 200. 199. 199. 199. 200. 201. + 201. 204. 204. 206. 201. 183. 165. 167. 180. 202. 196. 205. 205. + 212. 221. 197. 67. 38. 41. 43. 44. 45. 48. 52. 54. 53. 50. 48. 50. + 55. 56. 52. 48. 42. 80. 124. 149. 153. 150. 147. 146. 151. 154. 158. + 162. 163. 162. 160. 158. 160. 159. 158. 157. 157. 157. 157. 158. + 156. 156. 156. 156. 156. 156. 156. 156. 98. 98. 98. 98. 97. 97. 97. + 96. 96. 97. 97. 98. 103. 114. 129. 140. 152. 160. 167. 169. 171. + 175. 175. 172. 172. 172. 168. 160. 151. 139. 122. 106. 84. 78. 77. + 85. 93. 95. 94. 94. 97. 98. 100. 99. 98. 98. 100. 101. 99. 99. 100. + 101. 101. 102. 103. 103. 102. 103. 89. 123. 222. 195. 188. 170. 161. + 153. 144. 138. 134. 127. 118. 110. 110. 104. 101. 104. 108. 110. + 114. 119. 127. 107. 95. 107. 131. 146. 145. 139. 147. 139. 144. 153. + 141. 118. 117. 136. 154. 146. 146. 154. 157. 149. 141. 139. 150. + 156. 154. 149. 156. 169. 167. 155. 153. 162. 174. 178. 174. 169. + 169. 171. 162. 166. 171. 176. 178. 176. 172. 169. 162. 163. 164. + 166. 168. 170. 172. 173. 169. 173. 174. 171. 171. 179. 187. 190. + 182. 181. 182. 186. 190. 188. 180. 172. 178. 180. 181. 180. 176. + 173. 172. 172. 185. 171. 158. 160. 174. 188. 194. 195. 185. 184. + 185. 189. 195. 202. 206. 208. 202. 203. 202. 199. 195. 195. 199. + 203. 200. 199. 199. 199. 200. 201. 202. 203. 208. 208. 204. 188. + 166. 153. 160. 173. 193. 189. 193. 194. 202. 219. 157. 51. 44. 46. + 45. 44. 46. 51. 51. 48. 47. 46. 46. 47. 50. 51. 52. 51. 62. 99. 139. + 154. 150. 145. 148. 153. 157. 159. 161. 163. 164. 163. 162. 161. + 160. 159. 158. 157. 157. 157. 157. 158. 157. 157. 157. 157. 157. + 157. 157. 157. 98. 98. 98. 97. 97. 97. 96. 96. 96. 96. 97. 98. 103. + 114. 129. 140. 154. 162. 168. 170. 171. 174. 174. 171. 170. 171. + 169. 162. 153. 140. 122. 105. 86. 79. 76. 83. 91. 94. 95. 96. 97. + 99. 100. 99. 98. 98. 100. 102. 99. 99. 100. 101. 101. 102. 103. 103. + 98. 105. 88. 122. 220. 192. 190. 167. 166. 158. 149. 144. 141. 136. + 127. 118. 114. 103. 95. 99. 106. 112. 116. 120. 119. 107. 105. 122. + 143. 150. 142. 133. 141. 142. 146. 143. 127. 116. 128. 150. 152. + 146. 145. 150. 150. 144. 145. 150. 154. 152. 149. 147. 150. 154. + 154. 151. 163. 172. 178. 174. 165. 162. 168. 174. 167. 166. 166. + 169. 173. 172. 168. 164. 160. 161. 164. 166. 167. 167. 166. 165. + 162. 169. 173. 171. 170. 176. 182. 184. 186. 183. 180. 180. 182. + 182. 177. 172. 170. 175. 180. 181. 177. 171. 164. 161. 170. 165. + 166. 180. 199. 205. 193. 176. 178. 192. 204. 205. 198. 195. 202. + 212. 196. 196. 196. 195. 195. 196. 199. 201. 200. 200. 200. 200. + 201. 203. 204. 205. 208. 205. 193. 172. 156. 156. 166. 174. 164. + 165. 175. 193. 198. 205. 99. 44. 45. 51. 53. 50. 50. 53. 52. 47. 42. + 42. 42. 42. 44. 51. 60. 66. 91. 119. 146. 152. 144. 141. 148. 155. + 160. 161. 161. 162. 162. 162. 162. 161. 160. 159. 158. 157. 157. + 157. 157. 158. 157. 157. 157. 157. 157. 157. 157. 157. 98. 98. 98. + 97. 97. 96. 96. 96. 95. 96. 97. 98. 102. 114. 129. 140. 155. 163. + 169. 170. 171. 173. 173. 170. 169. 171. 169. 163. 154. 141. 121. + 105. 88. 80. 75. 80. 88. 93. 95. 98. 98. 99. 99. 99. 98. 98. 100. + 102. 99. 100. 100. 101. 101. 102. 102. 103. 94. 105. 87. 120. 219. + 192. 192. 165. 160. 153. 145. 142. 142. 140. 132. 125. 118. 103. 92. + 94. 103. 109. 113. 115. 102. 112. 129. 143. 146. 139. 135. 137. 132. + 149. 143. 114. 109. 136. 153. 149. 141. 154. 155. 141. 137. 151. + 159. 155. 144. 138. 141. 152. 156. 148. 147. 152. 175. 174. 170. + 166. 165. 166. 165. 163. 172. 167. 163. 163. 167. 168. 165. 160. + 167. 168. 168. 167. 164. 159. 155. 151. 160. 169. 176. 174. 171. + 171. 172. 172. 186. 183. 178. 174. 173. 173. 173. 173. 164. 171. + 179. 182. 177. 168. 158. 152. 152. 176. 199. 200. 186. 178. 184. + 194. 201. 201. 202. 203. 203. 200. 195. 191. 189. 190. 193. 195. + 197. 198. 197. 197. 200. 200. 200. 201. 202. 203. 205. 206. 204. + 199. 181. 159. 153. 166. 178. 180. 133. 140. 162. 199. 200. 192. 52. + 37. 39. 50. 56. 54. 51. 51. 49. 44. 46. 46. 46. 45. 48. 59. 75. 88. + 117. 136. 151. 151. 144. 144. 151. 158. 160. 159. 159. 158. 158. + 158. 159. 160. 160. 159. 158. 157. 157. 157. 157. 158. 157. 157. + 157. 157. 157. 157. 157. 157. 97. 97. 96. 95. 94. 94. 93. 92. 93. + 94. 95. 97. 103. 115. 131. 142. 155. 160. 166. 170. 172. 171. 171. + 171. 172. 171. 166. 159. 152. 142. 123. 107. 87. 78. 74. 79. 87. 92. + 94. 97. 97. 98. 99. 99. 97. 97. 98. 99. 98. 98. 100. 101. 101. 101. + 101. 101. 95. 102. 80. 138. 213. 191. 174. 173. 163. 162. 163. 144. + 139. 143. 145. 124. 107. 99. 92. 94. 105. 113. 109. 101. 104. 127. + 146. 146. 135. 130. 135. 142. 143. 128. 110. 117. 137. 140. 139. + 147. 151. 146. 141. 141. 144. 147. 147. 145. 145. 161. 168. 148. + 136. 157. 170. 156. 161. 158. 160. 167. 170. 168. 167. 169. 170. + 167. 169. 164. 155. 161. 173. 171. 161. 163. 168. 161. 151. 159. + 171. 168. 168. 162. 171. 175. 176. 174. 167. 173. 179. 184. 181. + 169. 165. 171. 175. 174. 166. 171. 175. 173. 167. 162. 162. 164. + 196. 192. 185. 178. 177. 181. 190. 196. 209. 207. 203. 200. 196. + 194. 193. 193. 191. 192. 194. 196. 197. 198. 198. 198. 199. 203. + 203. 199. 200. 206. 208. 205. 205. 194. 168. 147. 158. 179. 170. + 143. 136. 163. 178. 187. 221. 126. 42. 39. 33. 43. 54. 58. 54. 48. + 46. 46. 48. 53. 52. 45. 45. 61. 85. 101. 139. 148. 151. 145. 142. + 148. 157. 161. 162. 162. 161. 161. 160. 159. 158. 158. 159. 159. + 159. 158. 158. 157. 157. 157. 158. 158. 158. 157. 157. 156. 156. + 156. 97. 97. 96. 96. 95. 94. 93. 93. 92. 94. 95. 97. 102. 114. 130. + 141. 155. 160. 166. 170. 172. 171. 171. 171. 172. 171. 166. 160. + 153. 142. 123. 107. 88. 80. 75. 81. 88. 92. 95. 97. 98. 99. 101. + 100. 98. 98. 99. 100. 98. 99. 100. 100. 101. 101. 101. 100. 94. 95. + 80. 146. 208. 189. 177. 171. 159. 161. 149. 151. 127. 143. 133. 123. + 110. 104. 102. 105. 105. 103. 106. 113. 134. 142. 145. 138. 130. + 131. 137. 140. 126. 126. 121. 127. 141. 142. 139. 145. 143. 144. + 144. 142. 139. 139. 141. 144. 161. 149. 147. 148. 144. 150. 165. + 170. 164. 159. 155. 160. 169. 172. 166. 158. 158. 153. 160. 167. + 161. 162. 167. 165. 169. 151. 150. 161. 165. 166. 164. 155. 170. + 166. 172. 175. 174. 168. 160. 163. 165. 163. 168. 175. 176. 169. + 166. 169. 158. 164. 167. 163. 158. 162. 177. 191. 178. 180. 183. + 186. 189. 194. 199. 204. 201. 200. 198. 196. 194. 194. 194. 194. + 193. 194. 195. 197. 198. 199. 199. 199. 200. 201. 203. 204. 204. + 203. 207. 211. 209. 171. 149. 166. 184. 173. 148. 132. 160. 163. + 182. 195. 207. 94. 39. 36. 39. 43. 49. 52. 52. 48. 44. 41. 51. 47. + 48. 51. 54. 65. 91. 117. 145. 151. 151. 146. 144. 150. 157. 159. + 161. 161. 161. 160. 159. 158. 158. 157. 159. 159. 158. 158. 158. + 157. 157. 157. 158. 158. 157. 157. 157. 156. 156. 156. 97. 97. 96. + 96. 95. 94. 94. 94. 92. 94. 95. 97. 103. 114. 129. 140. 154. 159. + 166. 170. 172. 172. 171. 172. 172. 171. 167. 160. 153. 142. 123. + 106. 90. 81. 77. 82. 89. 93. 95. 97. 99. 100. 101. 101. 99. 98. 100. + 101. 98. 99. 99. 100. 101. 100. 100. 100. 94. 88. 84. 161. 204. 189. + 185. 173. 170. 152. 163. 140. 149. 128. 142. 126. 115. 112. 112. + 112. 104. 98. 109. 127. 150. 148. 141. 133. 131. 134. 134. 130. 110. + 127. 135. 138. 146. 146. 140. 142. 138. 140. 140. 137. 134. 137. + 144. 151. 155. 138. 141. 155. 155. 152. 155. 155. 152. 156. 156. + 154. 159. 166. 160. 149. 163. 157. 166. 177. 173. 167. 161. 151. + 150. 139. 152. 173. 172. 164. 171. 179. 156. 157. 161. 169. 172. + 169. 169. 170. 168. 164. 163. 166. 168. 167. 164. 163. 161. 153. + 149. 156. 172. 185. 188. 186. 171. 178. 187. 195. 199. 200. 201. + 201. 191. 191. 191. 191. 192. 193. 195. 195. 195. 196. 197. 199. + 200. 201. 201. 201. 202. 201. 203. 208. 208. 206. 207. 212. 188. + 159. 151. 171. 174. 152. 146. 160. 166. 158. 183. 207. 176. 56. 40. + 40. 47. 47. 47. 49. 51. 50. 46. 42. 53. 44. 44. 56. 63. 72. 103. + 137. 151. 152. 150. 146. 147. 153. 158. 158. 160. 160. 159. 159. + 158. 157. 156. 156. 159. 158. 158. 158. 157. 157. 157. 157. 158. + 157. 157. 157. 156. 156. 156. 156. 97. 97. 97. 96. 96. 95. 95. 94. + 94. 96. 97. 99. 105. 116. 130. 141. 154. 159. 166. 170. 172. 172. + 172. 172. 171. 171. 168. 161. 154. 143. 123. 106. 90. 81. 76. 81. + 88. 92. 93. 95. 98. 99. 100. 100. 98. 98. 99. 100. 98. 99. 99. 100. + 100. 100. 99. 99. 97. 83. 88. 179. 204. 193. 194. 179. 174. 167. + 147. 170. 135. 149. 133. 139. 121. 120. 113. 104. 101. 109. 123. + 134. 137. 138. 137. 135. 136. 135. 126. 116. 112. 134. 142. 141. + 148. 149. 142. 140. 139. 134. 130. 130. 136. 145. 153. 157. 137. + 140. 150. 156. 157. 164. 162. 146. 145. 161. 168. 158. 152. 154. + 151. 141. 154. 154. 159. 159. 157. 165. 162. 143. 162. 157. 168. + 177. 163. 153. 161. 169. 168. 170. 162. 165. 164. 158. 164. 161. + 161. 167. 165. 156. 158. 167. 164. 152. 161. 157. 158. 172. 189. + 194. 183. 170. 185. 190. 196. 199. 198. 194. 190. 188. 187. 187. + 188. 190. 191. 193. 195. 196. 197. 198. 200. 201. 202. 202. 202. + 202. 202. 205. 205. 204. 210. 215. 210. 200. 155. 160. 165. 162. + 154. 150. 155. 165. 144. 157. 189. 218. 129. 34. 44. 47. 53. 52. 51. + 51. 52. 53. 53. 53. 54. 48. 46. 54. 66. 86. 120. 150. 153. 150. 146. + 146. 150. 156. 159. 159. 159. 159. 158. 157. 157. 156. 155. 155. + 158. 158. 158. 157. 157. 157. 156. 156. 157. 157. 157. 156. 156. + 156. 155. 155. 97. 97. 97. 96. 96. 96. 96. 95. 96. 98. 101. 103. + 108. 118. 132. 142. 153. 158. 165. 170. 172. 172. 172. 173. 171. + 171. 168. 162. 155. 144. 124. 106. 87. 79. 74. 79. 86. 90. 92. 94. + 96. 97. 98. 98. 96. 96. 97. 98. 98. 99. 99. 100. 100. 99. 98. 98. + 97. 79. 87. 189. 204. 196. 197. 185. 182. 154. 168. 148. 162. 131. + 149. 140. 128. 124. 107. 90. 101. 128. 139. 132. 122. 130. 136. 136. + 133. 129. 121. 113. 128. 143. 143. 138. 145. 148. 141. 138. 136. + 128. 124. 132. 146. 155. 151. 143. 136. 143. 156. 159. 154. 161. + 165. 156. 144. 158. 162. 155. 152. 155. 147. 132. 128. 134. 130. + 112. 115. 150. 169. 154. 173. 161. 157. 158. 158. 166. 166. 153. + 165. 172. 157. 161. 161. 157. 172. 166. 152. 156. 160. 162. 161. + 158. 153. 148. 160. 175. 188. 189. 179. 173. 179. 187. 199. 200. + 199. 195. 190. 186. 183. 183. 188. 189. 190. 192. 193. 195. 195. + 196. 199. 200. 201. 202. 203. 203. 203. 203. 202. 210. 207. 199. + 209. 223. 209. 179. 153. 161. 162. 155. 150. 147. 134. 119. 127. + 175. 205. 215. 79. 32. 41. 47. 51. 53. 55. 53. 50. 52. 58. 64. 54. + 56. 52. 50. 68. 104. 137. 152. 150. 145. 143. 146. 153. 158. 160. + 160. 159. 158. 158. 157. 156. 155. 155. 155. 158. 158. 157. 157. + 157. 156. 156. 156. 157. 157. 156. 156. 156. 155. 155. 155. 97. 97. + 97. 97. 97. 96. 96. 96. 98. 100. 103. 105. 110. 120. 133. 143. 153. + 158. 165. 170. 172. 172. 173. 173. 171. 172. 169. 163. 156. 144. + 124. 106. 85. 76. 72. 78. 86. 90. 92. 95. 95. 96. 98. 97. 95. 95. + 96. 97. 98. 99. 99. 99. 99. 98. 97. 97. 94. 77. 80. 190. 205. 198. + 194. 188. 180. 172. 154. 174. 144. 157. 145. 151. 137. 126. 104. 90. + 107. 137. 143. 129. 124. 133. 137. 130. 122. 120. 123. 125. 142. + 147. 139. 134. 141. 142. 135. 135. 129. 127. 129. 140. 151. 151. + 139. 126. 142. 141. 158. 170. 153. 133. 130. 130. 126. 124. 122. + 127. 144. 155. 145. 127. 135. 140. 129. 99. 94. 136. 168. 163. 164. + 161. 162. 158. 153. 163. 168. 156. 155. 169. 153. 161. 160. 149. + 164. 149. 173. 159. 157. 163. 154. 138. 147. 171. 181. 185. 186. + 180. 173. 176. 190. 203. 198. 198. 195. 191. 187. 186. 188. 190. + 191. 192. 194. 195. 196. 197. 197. 197. 200. 201. 202. 203. 203. + 203. 203. 203. 203. 210. 207. 200. 209. 219. 197. 162. 170. 158. + 148. 138. 120. 101. 100. 112. 145. 203. 218. 179. 45. 39. 34. 41. + 47. 51. 53. 50. 46. 48. 57. 66. 54. 59. 55. 55. 80. 123. 148. 150. + 147. 143. 143. 149. 156. 158. 159. 161. 159. 159. 158. 157. 157. + 156. 155. 155. 157. 157. 157. 157. 156. 156. 156. 155. 156. 156. + 156. 156. 155. 155. 155. 154. 97. 97. 97. 97. 97. 97. 97. 97. 98. + 100. 103. 106. 110. 120. 132. 142. 152. 158. 165. 170. 172. 173. + 173. 174. 171. 172. 169. 164. 157. 145. 124. 106. 84. 76. 72. 78. + 87. 92. 95. 97. 96. 97. 98. 98. 96. 95. 97. 98. 99. 99. 99. 99. 99. + 98. 97. 96. 93. 79. 74. 189. 208. 202. 191. 194. 183. 166. 172. 157. + 162. 149. 162. 151. 146. 127. 108. 107. 119. 130. 132. 129. 128. + 134. 133. 122. 114. 118. 130. 138. 143. 144. 137. 135. 139. 132. + 125. 131. 127. 134. 141. 144. 141. 137. 135. 135. 146. 145. 154. + 152. 130. 115. 114. 112. 115. 106. 100. 105. 118. 127. 125. 119. + 156. 159. 157. 134. 113. 124. 142. 143. 156. 158. 169. 167. 149. + 140. 144. 144. 151. 172. 155. 163. 151. 122. 123. 92. 146. 154. 158. + 151. 141. 145. 167. 188. 188. 178. 170. 175. 189. 200. 201. 197. + 193. 193. 193. 192. 190. 190. 192. 194. 192. 194. 196. 197. 199. + 199. 199. 198. 201. 201. 202. 203. 203. 203. 203. 202. 206. 206. + 207. 211. 212. 202. 178. 156. 157. 135. 117. 106. 85. 74. 104. 148. + 181. 215. 211. 113. 29. 45. 33. 41. 49. 49. 48. 46. 45. 48. 55. 60. + 54. 54. 55. 69. 102. 137. 152. 150. 147. 144. 147. 155. 159. 158. + 158. 161. 160. 159. 159. 158. 157. 156. 156. 156. 157. 157. 157. + 156. 156. 156. 155. 155. 156. 156. 156. 155. 155. 155. 154. 154. 97. + 97. 97. 97. 97. 97. 97. 97. 97. 100. 103. 105. 110. 119. 131. 141. + 152. 157. 165. 170. 172. 173. 173. 174. 171. 172. 170. 164. 157. + 145. 124. 105. 84. 76. 72. 79. 88. 93. 97. 99. 97. 98. 99. 99. 97. + 97. 98. 99. 99. 99. 99. 99. 99. 97. 96. 96. 95. 83. 72. 189. 213. + 207. 191. 199. 174. 167. 160. 160. 147. 154. 155. 148. 153. 127. + 115. 125. 129. 119. 119. 131. 125. 130. 128. 119. 113. 120. 134. + 144. 139. 139. 136. 138. 139. 125. 118. 128. 130. 142. 149. 142. + 127. 125. 141. 159. 155. 157. 142. 107. 92. 120. 146. 140. 130. 124. + 116. 106. 94. 87. 94. 106. 151. 157. 173. 169. 137. 114. 112. 113. + 119. 108. 123. 152. 159. 154. 152. 150. 106. 139. 134. 155. 150. + 119. 117. 81. 62. 123. 158. 144. 143. 176. 193. 180. 166. 170. 179. + 193. 204. 206. 199. 191. 191. 193. 196. 196. 194. 192. 190. 190. + 192. 193. 196. 198. 200. 200. 200. 200. 201. 201. 202. 203. 203. + 203. 202. 202. 208. 200. 206. 221. 215. 186. 163. 157. 124. 99. 79. + 79. 87. 103. 132. 162. 206. 210. 194. 58. 25. 49. 37. 47. 54. 50. + 45. 44. 47. 51. 54. 55. 55. 47. 53. 83. 120. 144. 152. 152. 148. + 147. 151. 160. 162. 157. 156. 160. 160. 160. 159. 159. 158. 157. + 156. 156. 157. 157. 157. 156. 156. 155. 155. 155. 156. 156. 156. + 155. 155. 154. 154. 154. 96. 96. 96. 97. 97. 97. 98. 98. 98. 100. + 103. 105. 110. 119. 133. 142. 154. 161. 169. 173. 173. 173. 174. + 176. 173. 173. 170. 165. 158. 146. 125. 107. 86. 77. 72. 77. 85. 89. + 92. 95. 95. 97. 98. 98. 98. 98. 99. 101. 99. 100. 100. 100. 99. 97. + 95. 94. 85. 70. 90. 175. 209. 201. 206. 187. 186. 180. 172. 162. + 151. 143. 145. 152. 157. 134. 115. 115. 119. 118. 119. 125. 135. + 121. 108. 109. 124. 139. 144. 143. 137. 136. 134. 128. 123. 123. + 127. 132. 134. 138. 131. 145. 127. 136. 134. 152. 146. 140. 131. + 127. 133. 140. 136. 128. 115. 122. 103. 99. 95. 96. 66. 101. 153. + 169. 165. 159. 131. 131. 124. 128. 129. 105. 106. 88. 102. 113. 133. + 137. 113. 102. 89. 59. 74. 68. 88. 99. 31. 83. 140. 163. 188. 188. + 158. 160. 174. 179. 188. 195. 198. 197. 194. 191. 196. 197. 197. + 195. 193. 193. 194. 196. 192. 194. 199. 203. 203. 200. 199. 200. + 199. 197. 203. 205. 200. 205. 208. 198. 205. 209. 213. 209. 188. + 155. 127. 113. 81. 77. 94. 102. 94. 116. 166. 194. 215. 220. 86. 44. + 42. 40. 51. 48. 41. 46. 46. 41. 42. 50. 55. 54. 46. 44. 65. 109. + 145. 154. 150. 148. 142. 150. 159. 162. 161. 159. 160. 162. 159. + 159. 158. 157. 157. 156. 155. 155. 155. 155. 155. 154. 154. 153. + 153. 153. 154. 154. 154. 154. 154. 154. 154. 154. 97. 98. 99. 99. + 99. 99. 98. 98. 101. 103. 106. 108. 112. 122. 136. 145. 154. 161. + 169. 173. 173. 173. 174. 175. 173. 173. 170. 165. 158. 146. 125. + 107. 86. 77. 72. 77. 85. 89. 93. 95. 95. 97. 98. 98. 98. 98. 99. + 101. 97. 98. 99. 100. 100. 98. 97. 96. 95. 76. 90. 162. 215. 203. + 206. 192. 193. 186. 174. 159. 144. 137. 144. 155. 151. 129. 112. + 114. 121. 122. 124. 129. 116. 113. 113. 123. 136. 142. 139. 133. + 139. 137. 132. 126. 123. 124. 127. 131. 138. 137. 126. 138. 130. + 144. 140. 148. 155. 129. 114. 127. 145. 142. 120. 100. 116. 101. 86. + 79. 73. 66. 60. 105. 144. 147. 171. 142. 152. 118. 123. 105. 106. + 97. 89. 76. 105. 89. 71. 65. 69. 73. 74. 51. 58. 41. 46. 49. 34. 65. + 160. 198. 162. 152. 165. 174. 191. 193. 195. 197. 197. 196. 193. + 191. 196. 196. 196. 195. 193. 192. 194. 196. 199. 196. 195. 197. + 200. 201. 203. 204. 200. 203. 210. 205. 192. 197. 210. 211. 217. + 199. 177. 156. 135. 112. 94. 87. 91. 86. 87. 96. 115. 153. 186. 195. + 227. 144. 54. 37. 41. 44. 41. 48. 45. 48. 47. 44. 45. 51. 53. 51. + 44. 50. 77. 119. 147. 151. 147. 146. 145. 152. 160. 163. 161. 159. + 159. 161. 159. 159. 158. 158. 157. 156. 155. 155. 155. 155. 155. + 154. 154. 154. 153. 153. 154. 154. 154. 154. 154. 154. 154. 154. 98. + 99. 101. 102. 102. 101. 99. 97. 102. 104. 106. 109. 113. 123. 137. + 146. 154. 160. 168. 173. 173. 172. 173. 175. 173. 173. 170. 165. + 158. 146. 125. 107. 86. 77. 72. 77. 85. 90. 93. 96. 95. 97. 98. 98. + 98. 98. 99. 101. 95. 96. 98. 99. 100. 99. 98. 97. 102. 80. 87. 139. + 221. 203. 202. 196. 198. 192. 180. 160. 138. 126. 132. 145. 138. + 119. 105. 109. 117. 120. 121. 123. 103. 109. 119. 133. 142. 143. + 136. 129. 136. 132. 127. 125. 126. 129. 131. 133. 138. 135. 124. + 132. 135. 151. 143. 139. 120. 116. 126. 146. 144. 120. 102. 101. + 104. 84. 100. 106. 105. 83. 87. 122. 119. 137. 127. 144. 109. 113. + 76. 70. 66. 44. 89. 116. 93. 46. 68. 84. 40. 51. 51. 32. 45. 45. 44. + 34. 65. 128. 182. 168. 154. 168. 178. 198. 202. 201. 199. 197. 195. + 193. 193. 192. 195. 195. 196. 194. 192. 192. 194. 195. 200. 198. + 195. 195. 198. 201. 201. 199. 202. 197. 203. 209. 210. 213. 206. + 186. 168. 143. 114. 99. 92. 88. 83. 81. 91. 89. 95. 122. 156. 177. + 200. 229. 194. 66. 44. 38. 42. 56. 45. 51. 50. 50. 48. 47. 50. 53. + 50. 44. 40. 60. 96. 133. 150. 148. 143. 143. 150. 155. 161. 163. + 161. 159. 159. 160. 159. 159. 159. 158. 157. 156. 156. 155. 155. + 155. 155. 155. 154. 154. 154. 153. 154. 154. 154. 154. 154. 154. + 154. 154. 98. 100. 103. 104. 103. 101. 98. 95. 100. 103. 105. 107. + 112. 122. 135. 145. 153. 160. 168. 172. 172. 172. 173. 175. 173. + 173. 170. 165. 158. 146. 125. 107. 86. 77. 72. 77. 85. 90. 93. 96. + 95. 97. 98. 98. 98. 98. 99. 101. 96. 97. 99. 100. 100. 99. 97. 97. + 101. 80. 82. 114. 220. 205. 198. 197. 198. 195. 185. 163. 134. 115. + 117. 129. 131. 117. 108. 111. 117. 118. 114. 113. 107. 114. 125. + 134. 139. 138. 134. 132. 125. 123. 122. 126. 132. 136. 136. 135. + 131. 132. 129. 134. 140. 148. 138. 125. 99. 116. 138. 142. 123. 104. + 111. 130. 126. 105. 134. 131. 124. 89. 82. 90. 94. 99. 113. 103. + 102. 78. 70. 57. 56. 108. 101. 59. 83. 82. 80. 66. 54. 44. 35. 34. + 41. 40. 67. 107. 142. 175. 170. 136. 163. 201. 197. 209. 198. 197. + 195. 194. 192. 192. 192. 192. 193. 194. 195. 193. 192. 192. 193. + 195. 194. 198. 200. 199. 199. 200. 197. 193. 200. 197. 206. 213. + 207. 192. 161. 124. 103. 90. 80. 82. 89. 92. 91. 91. 93. 114. 127. + 150. 187. 196. 188. 192. 107. 32. 57. 41. 44. 58. 55. 51. 52. 50. + 48. 49. 53. 53. 47. 39. 39. 71. 115. 145. 151. 145. 142. 144. 155. + 159. 162. 163. 161. 159. 158. 159. 160. 160. 159. 158. 157. 157. + 156. 156. 156. 156. 155. 155. 155. 154. 154. 154. 155. 155. 154. + 154. 154. 154. 153. 153. 99. 101. 103. 104. 103. 100. 96. 94. 100. + 103. 105. 107. 112. 122. 135. 145. 153. 160. 168. 172. 172. 171. + 173. 174. 173. 173. 170. 165. 158. 146. 125. 107. 87. 78. 73. 78. + 86. 91. 94. 96. 95. 97. 98. 98. 98. 98. 99. 101. 99. 99. 100. 100. + 99. 97. 95. 94. 97. 81. 81. 97. 209. 210. 198. 199. 200. 196. 184. + 160. 130. 112. 119. 134. 137. 129. 122. 122. 122. 118. 112. 108. + 116. 124. 133. 137. 137. 133. 131. 130. 119. 120. 123. 130. 136. + 138. 135. 131. 124. 130. 139. 139. 142. 135. 126. 115. 127. 132. + 128. 116. 112. 121. 130. 131. 120. 97. 110. 87. 84. 68. 66. 63. 72. + 84. 108. 105. 106. 86. 91. 90. 113. 83. 83. 85. 65. 45. 86. 73. 59. + 43. 31. 42. 37. 39. 94. 180. 179. 136. 152. 174. 176. 194. 202. 200. + 193. 193. 193. 193. 193. 192. 190. 189. 192. 193. 193. 193. 191. + 191. 193. 195. 190. 198. 203. 199. 197. 200. 202. 201. 208. 212. + 214. 190. 147. 116. 99. 83. 87. 83. 84. 90. 96. 97. 98. 101. 117. + 156. 168. 172. 202. 199. 135. 73. 40. 36. 53. 39. 52. 46. 51. 47. + 51. 48. 47. 51. 55. 53. 46. 39. 46. 85. 129. 151. 149. 143. 144. + 148. 160. 162. 163. 162. 161. 159. 159. 159. 160. 160. 159. 159. + 158. 157. 156. 156. 156. 156. 156. 155. 155. 155. 154. 154. 155. + 155. 155. 154. 154. 153. 153. 153. 101. 102. 103. 103. 102. 99. 96. + 94. 102. 104. 106. 109. 113. 123. 137. 146. 153. 159. 167. 171. 172. + 171. 172. 174. 173. 173. 170. 165. 158. 146. 125. 107. 87. 78. 73. + 78. 86. 91. 94. 97. 95. 97. 98. 98. 98. 98. 99. 101. 100. 100. 100. + 100. 99. 97. 95. 93. 96. 88. 85. 87. 187. 214. 203. 203. 205. 197. + 181. 156. 129. 119. 132. 151. 142. 138. 131. 124. 117. 111. 108. + 107. 122. 130. 139. 143. 139. 132. 125. 122. 121. 123. 128. 133. + 135. 134. 129. 124. 125. 130. 145. 141. 139. 118. 117. 116. 134. + 140. 134. 118. 116. 123. 115. 97. 86. 73. 72. 50. 57. 64. 63. 68. + 77. 103. 105. 130. 93. 102. 91. 112. 75. 118. 97. 63. 69. 49. 84. + 99. 32. 49. 33. 29. 55. 119. 150. 165. 127. 135. 176. 196. 194. 191. + 182. 190. 193. 194. 195. 195. 193. 191. 187. 185. 191. 192. 192. + 192. 190. 191. 193. 195. 193. 200. 200. 194. 194. 202. 208. 207. + 214. 202. 181. 141. 97. 82. 87. 87. 85. 84. 87. 93. 99. 107. 121. + 134. 152. 169. 195. 215. 200. 136. 65. 31. 37. 52. 37. 44. 65. 40. + 45. 50. 48. 46. 47. 54. 57. 54. 48. 46. 65. 103. 141. 152. 146. 144. + 149. 154. 164. 164. 163. 162. 161. 160. 160. 160. 161. 160. 160. + 159. 158. 157. 157. 157. 157. 156. 156. 156. 155. 155. 155. 155. + 156. 156. 155. 154. 154. 153. 152. 152. 105. 105. 104. 103. 102. 99. + 97. 96. 101. 103. 106. 108. 112. 122. 136. 145. 152. 159. 167. 171. + 171. 171. 172. 174. 173. 173. 170. 165. 158. 146. 125. 107. 87. 79. + 73. 78. 86. 91. 94. 97. 95. 97. 98. 98. 98. 98. 99. 101. 98. 99. + 100. 100. 99. 98. 96. 95. 98. 96. 87. 80. 158. 214. 205. 203. 203. + 196. 182. 160. 136. 126. 137. 153. 144. 142. 134. 120. 107. 104. + 108. 114. 129. 134. 139. 140. 135. 129. 123. 119. 124. 127. 131. + 133. 131. 128. 126. 125. 137. 131. 143. 135. 132. 104. 116. 128. + 124. 133. 132. 116. 99. 90. 86. 81. 88. 83. 68. 55. 56. 61. 47. 73. + 107. 103. 122. 89. 91. 58. 88. 100. 116. 92. 77. 90. 82. 45. 82. 71. + 23. 46. 38. 62. 114. 183. 165. 129. 117. 179. 205. 183. 192. 196. + 173. 187. 192. 193. 193. 192. 191. 189. 186. 185. 190. 191. 192. + 191. 190. 190. 192. 194. 194. 198. 197. 193. 196. 202. 196. 183. + 169. 154. 139. 117. 96. 96. 101. 96. 87. 91. 100. 113. 125. 137. + 153. 166. 177. 173. 199. 212. 149. 59. 33. 54. 48. 58. 38. 55. 61. + 49. 46. 51. 46. 45. 49. 57. 60. 56. 54. 56. 90. 123. 150. 151. 143. + 146. 155. 159. 166. 165. 163. 162. 162. 162. 162. 161. 161. 161. + 160. 159. 158. 158. 157. 157. 157. 157. 156. 156. 156. 155. 155. + 155. 156. 156. 155. 154. 154. 153. 152. 152. 108. 107. 106. 104. + 102. 100. 99. 98. 98. 100. 103. 105. 110. 119. 133. 142. 152. 159. + 167. 171. 171. 171. 172. 174. 173. 173. 170. 165. 158. 146. 125. + 107. 88. 79. 74. 79. 87. 91. 94. 97. 95. 97. 98. 98. 98. 98. 99. + 101. 96. 97. 98. 99. 100. 99. 98. 97. 99. 100. 87. 73. 134. 209. + 203. 201. 196. 193. 185. 169. 146. 130. 131. 140. 149. 148. 138. + 119. 104. 104. 116. 127. 138. 137. 135. 131. 128. 125. 124. 124. + 124. 127. 130. 130. 128. 126. 128. 130. 149. 132. 138. 127. 127. 98. + 119. 140. 139. 124. 102. 79. 62. 60. 75. 93. 83. 77. 51. 49. 50. 60. + 50. 104. 118. 113. 91. 77. 45. 50. 68. 101. 58. 105. 95. 69. 61. 41. + 81. 67. 47. 29. 46. 142. 174. 152. 113. 137. 189. 181. 199. 186. + 166. 181. 187. 184. 189. 188. 188. 187. 187. 187. 187. 187. 189. + 190. 191. 191. 190. 190. 192. 194. 192. 195. 196. 196. 202. 200. + 177. 149. 95. 111. 132. 130. 108. 97. 97. 92. 109. 116. 132. 150. + 162. 165. 167. 171. 188. 192. 194. 150. 73. 37. 43. 46. 39. 51. 51. + 61. 42. 58. 49. 43. 45. 45. 51. 60. 62. 58. 58. 64. 108. 136. 156. + 150. 141. 147. 158. 162. 167. 165. 162. 161. 162. 163. 163. 162. + 161. 161. 160. 159. 159. 158. 157. 157. 157. 157. 157. 156. 156. + 155. 155. 155. 156. 156. 155. 154. 154. 153. 152. 152. 108. 106. + 104. 104. 104. 104. 102. 100. 99. 101. 104. 106. 111. 121. 134. 144. + 153. 160. 167. 171. 170. 169. 168. 169. 171. 172. 169. 163. 157. + 146. 127. 110. 85. 79. 76. 80. 85. 87. 92. 97. 93. 94. 95. 96. 97. + 97. 97. 97. 100. 99. 98. 97. 98. 99. 100. 101. 100. 94. 102. 71. 91. + 201. 199. 210. 198. 199. 184. 172. 160. 133. 128. 156. 136. 152. + 134. 104. 104. 114. 124. 140. 133. 136. 136. 129. 120. 116. 121. + 128. 127. 126. 129. 130. 125. 121. 130. 144. 135. 145. 134. 144. + 134. 87. 140. 134. 113. 89. 70. 54. 67. 98. 93. 69. 45. 70. 50. 49. + 64. 35. 90. 126. 110. 122. 70. 50. 42. 51. 102. 94. 70. 99. 90. 51. + 27. 32. 110. 86. 32. 82. 143. 167. 147. 130. 154. 192. 196. 193. + 188. 183. 180. 180. 183. 186. 185. 187. 188. 188. 187. 185. 185. + 186. 190. 189. 187. 186. 189. 195. 198. 199. 201. 197. 206. 180. + 199. 170. 76. 103. 106. 109. 139. 137. 135. 116. 136. 140. 153. 160. + 166. 169. 169. 168. 168. 167. 184. 202. 151. 63. 33. 46. 50. 45. 52. + 52. 53. 53. 53. 52. 51. 51. 37. 49. 53. 61. 65. 46. 47. 80. 132. + 144. 150. 145. 140. 147. 159. 165. 161. 163. 164. 165. 165. 163. + 161. 159. 161. 161. 160. 159. 159. 158. 157. 157. 159. 158. 156. + 155. 154. 155. 156. 157. 156. 156. 155. 154. 154. 153. 152. 152. + 108. 106. 105. 104. 104. 104. 102. 100. 100. 102. 104. 106. 111. + 121. 134. 144. 153. 160. 167. 171. 171. 169. 169. 170. 171. 172. + 169. 163. 157. 147. 127. 110. 86. 78. 75. 79. 85. 89. 92. 95. 94. + 95. 96. 98. 98. 99. 99. 99. 99. 99. 97. 97. 97. 98. 100. 101. 98. + 95. 94. 80. 83. 169. 216. 196. 188. 196. 194. 185. 173. 154. 136. + 134. 149. 136. 111. 100. 116. 130. 133. 135. 142. 134. 123. 113. + 111. 116. 125. 132. 129. 132. 129. 121. 119. 124. 126. 122. 136. + 133. 134. 152. 153. 109. 122. 97. 80. 61. 65. 85. 93. 75. 51. 46. + 56. 57. 46. 47. 54. 54. 114. 104. 109. 86. 46. 40. 71. 107. 108. 73. + 80. 89. 67. 38. 45. 52. 94. 72. 89. 145. 169. 139. 125. 157. 191. + 196. 190. 188. 185. 181. 179. 181. 184. 187. 183. 184. 185. 184. + 183. 183. 186. 188. 185. 190. 193. 193. 192. 191. 188. 184. 188. + 188. 207. 162. 82. 80. 101. 76. 104. 105. 120. 145. 152. 160. 161. + 160. 163. 159. 161. 168. 168. 166. 177. 192. 222. 156. 71. 30. 36. + 46. 45. 47. 55. 55. 55. 54. 52. 50. 47. 46. 48. 54. 51. 51. 52. 44. + 59. 101. 137. 146. 150. 145. 143. 151. 161. 167. 162. 164. 165. 166. + 165. 164. 162. 160. 161. 161. 160. 160. 159. 158. 157. 157. 159. + 158. 156. 155. 155. 155. 156. 156. 156. 156. 155. 154. 154. 153. + 152. 152. 109. 107. 105. 104. 105. 104. 102. 100. 101. 102. 104. + 106. 110. 121. 134. 144. 153. 159. 168. 172. 171. 169. 169. 170. + 172. 172. 169. 164. 158. 147. 128. 111. 87. 78. 72. 78. 86. 91. 92. + 93. 95. 96. 97. 99. 99. 100. 100. 99. 98. 98. 97. 96. 97. 98. 100. + 101. 100. 100. 90. 91. 79. 126. 225. 194. 200. 202. 199. 184. 171. + 172. 164. 142. 163. 125. 104. 113. 127. 135. 137. 132. 140. 128. + 113. 108. 112. 121. 128. 130. 126. 132. 127. 115. 120. 133. 130. + 113. 92. 97. 128. 140. 129. 94. 90. 83. 58. 72. 76. 76. 75. 61. 44. + 40. 68. 45. 42. 46. 50. 76. 129. 71. 84. 48. 48. 63. 95. 122. 104. + 87. 93. 45. 49. 61. 53. 51. 96. 109. 160. 152. 139. 137. 157. 185. + 200. 199. 185. 183. 181. 179. 179. 182. 185. 187. 181. 181. 180. + 179. 179. 181. 186. 189. 191. 193. 191. 188. 190. 196. 199. 198. + 203. 176. 97. 74. 66. 75. 125. 110. 105. 110. 110. 147. 153. 176. + 163. 164. 167. 170. 171. 169. 170. 180. 198. 212. 160. 82. 30. 35. + 46. 44. 45. 53. 54. 55. 56. 55. 53. 50. 46. 44. 52. 57. 52. 46. 44. + 46. 75. 120. 144. 147. 147. 145. 147. 156. 165. 168. 164. 165. 166. + 166. 166. 165. 163. 162. 161. 161. 161. 160. 159. 158. 158. 157. + 158. 158. 157. 156. 155. 155. 156. 156. 156. 156. 155. 154. 154. + 153. 152. 152. 109. 107. 105. 105. 105. 104. 102. 100. 101. 102. + 103. 105. 109. 120. 134. 144. 153. 159. 168. 172. 171. 170. 170. + 171. 172. 172. 170. 164. 158. 147. 128. 111. 88. 77. 70. 76. 87. 92. + 92. 91. 95. 96. 97. 98. 99. 99. 99. 99. 98. 97. 96. 96. 96. 98. 100. + 101. 105. 104. 96. 96. 87. 94. 200. 209. 210. 200. 195. 180. 164. + 175. 182. 162. 147. 110. 108. 129. 128. 126. 135. 138. 125. 120. + 116. 119. 125. 128. 125. 121. 119. 124. 124. 121. 130. 142. 140. + 127. 130. 91. 97. 103. 113. 109. 71. 50. 69. 94. 82. 62. 54. 52. 62. + 66. 69. 42. 40. 48. 65. 85. 110. 46. 61. 38. 59. 97. 101. 93. 97. + 106. 73. 36. 80. 82. 33. 68. 145. 159. 153. 119. 119. 166. 199. 194. + 188. 198. 184. 182. 180. 179. 180. 182. 184. 184. 178. 177. 176. + 175. 175. 179. 185. 190. 194. 193. 189. 186. 192. 200. 196. 185. + 139. 62. 38. 105. 87. 69. 135. 126. 107. 117. 118. 138. 146. 160. + 156. 164. 170. 174. 170. 169. 188. 207. 194. 164. 63. 35. 38. 54. + 49. 45. 51. 50. 50. 52. 54. 54. 54. 51. 48. 46. 47. 53. 56. 51. 47. + 55. 89. 127. 147. 145. 143. 145. 152. 160. 166. 168. 165. 166. 166. + 167. 166. 165. 164. 163. 162. 162. 161. 160. 159. 159. 158. 158. + 158. 158. 157. 157. 156. 156. 156. 156. 156. 156. 155. 154. 154. + 153. 152. 152. 110. 108. 106. 105. 105. 105. 103. 101. 101. 102. + 102. 103. 107. 118. 132. 143. 152. 159. 168. 172. 172. 171. 171. + 172. 172. 173. 170. 165. 158. 148. 129. 111. 88. 76. 70. 76. 87. 92. + 92. 91. 93. 94. 95. 97. 98. 98. 98. 98. 97. 97. 96. 96. 97. 99. 101. + 102. 107. 103. 104. 93. 97. 81. 148. 218. 206. 195. 196. 187. 167. + 169. 177. 167. 122. 96. 106. 133. 129. 123. 132. 137. 109. 114. 122. + 128. 131. 127. 121. 116. 119. 120. 125. 133. 137. 137. 136. 136. + 102. 79. 96. 86. 70. 79. 67. 85. 85. 87. 68. 72. 62. 44. 70. 93. 52. + 41. 39. 51. 91. 83. 74. 41. 55. 55. 56. 92. 88. 77. 104. 79. 34. 96. + 121. 55. 31. 123. 172. 150. 107. 134. 169. 191. 195. 192. 190. 192. + 186. 184. 181. 180. 182. 183. 181. 180. 175. 175. 174. 174. 175. + 179. 185. 190. 187. 190. 191. 193. 198. 191. 162. 129. 82. 39. 56. + 114. 104. 77. 105. 136. 115. 119. 121. 118. 148. 152. 162. 170. 174. + 168. 169. 187. 203. 186. 129. 75. 48. 32. 39. 48. 42. 46. 54. 46. + 51. 52. 53. 53. 52. 50. 48. 46. 46. 50. 56. 54. 51. 68. 104. 131. + 144. 141. 140. 146. 156. 163. 166. 166. 166. 166. 166. 166. 165. + 165. 164. 164. 162. 162. 161. 161. 160. 159. 158. 158. 158. 158. + 158. 158. 157. 157. 156. 156. 156. 156. 155. 154. 154. 153. 152. + 152. 110. 108. 106. 105. 106. 105. 103. 101. 101. 101. 101. 101. + 105. 115. 130. 141. 152. 159. 168. 172. 173. 171. 172. 173. 173. + 173. 170. 165. 159. 148. 129. 112. 86. 76. 71. 76. 85. 90. 91. 92. + 93. 94. 95. 96. 97. 97. 97. 97. 98. 97. 97. 97. 98. 100. 102. 104. + 106. 101. 106. 94. 100. 83. 103. 189. 213. 208. 202. 187. 168. 168. + 177. 178. 127. 112. 115. 133. 137. 131. 125. 120. 108. 115. 123. + 127. 126. 123. 120. 120. 123. 123. 130. 138. 134. 123. 120. 125. 99. + 63. 57. 61. 65. 93. 75. 76. 79. 80. 55. 54. 47. 57. 99. 89. 34. 40. + 41. 54. 105. 77. 49. 49. 45. 73. 62. 68. 55. 72. 109. 44. 33. 140. + 105. 40. 80. 141. 124. 118. 136. 173. 202. 200. 192. 193. 194. 188. + 187. 184. 181. 181. 182. 182. 179. 175. 172. 174. 175. 176. 177. + 180. 184. 187. 189. 190. 187. 186. 191. 187. 156. 120. 85. 96. 79. + 61. 104. 113. 86. 124. 130. 125. 115. 100. 148. 152. 162. 165. 167. + 173. 195. 209. 172. 100. 51. 40. 51. 37. 40. 51. 46. 40. 49. 60. 57. + 56. 55. 52. 50. 47. 44. 43. 54. 50. 53. 53. 54. 83. 121. 137. 138. + 135. 138. 150. 161. 166. 166. 165. 166. 165. 165. 165. 164. 164. + 164. 164. 163. 162. 162. 161. 160. 159. 159. 159. 158. 158. 159. + 159. 158. 157. 156. 156. 156. 156. 155. 154. 154. 153. 152. 152. + 110. 108. 106. 106. 106. 105. 104. 102. 100. 100. 99. 98. 102. 113. + 128. 139. 152. 159. 168. 173. 173. 172. 172. 174. 173. 173. 171. + 165. 159. 148. 129. 112. 84. 77. 73. 77. 84. 87. 90. 93. 94. 95. 96. + 97. 98. 98. 98. 98. 99. 98. 98. 98. 99. 102. 104. 105. 106. 102. + 105. 105. 96. 93. 87. 130. 204. 219. 209. 183. 175. 181. 182. 180. + 130. 135. 131. 129. 136. 132. 119. 113. 117. 121. 126. 128. 127. + 125. 124. 125. 120. 127. 133. 133. 127. 120. 113. 108. 107. 101. 97. + 94. 61. 71. 72. 88. 63. 69. 44. 34. 32. 80. 128. 69. 33. 40. 50. 57. + 97. 70. 45. 52. 46. 64. 67. 55. 39. 74. 99. 35. 66. 132. 86. 90. + 123. 110. 92. 130. 189. 190. 194. 197. 198. 195. 188. 183. 185. 181. + 178. 179. 182. 182. 177. 172. 170. 174. 178. 181. 182. 182. 183. + 184. 188. 189. 183. 177. 184. 193. 179. 156. 86. 72. 102. 97. 76. + 100. 104. 82. 129. 135. 114. 103. 136. 150. 153. 168. 175. 186. 192. + 165. 99. 39. 28. 48. 36. 42. 49. 57. 57. 45. 47. 65. 59. 57. 54. 50. + 47. 45. 44. 44. 59. 50. 54. 57. 64. 99. 133. 137. 131. 131. 140. + 156. 167. 168. 166. 166. 165. 165. 164. 163. 163. 163. 163. 163. + 163. 163. 162. 161. 160. 160. 159. 159. 158. 158. 159. 159. 159. + 158. 156. 155. 156. 156. 155. 154. 154. 153. 152. 152. 110. 108. + 106. 106. 106. 106. 104. 102. 99. 99. 98. 97. 101. 112. 127. 138. + 152. 159. 168. 173. 173. 172. 173. 174. 173. 174. 171. 165. 159. + 148. 129. 112. 82. 77. 74. 78. 83. 85. 90. 95. 95. 96. 97. 98. 99. + 100. 99. 99. 99. 99. 99. 99. 100. 103. 105. 106. 107. 106. 103. 118. + 93. 102. 92. 81. 166. 209. 211. 188. 192. 197. 176. 156. 106. 134. + 134. 120. 125. 127. 120. 124. 124. 127. 130. 133. 134. 132. 129. + 126. 113. 127. 133. 125. 123. 127. 118. 101. 91. 89. 78. 89. 66. 83. + 90. 100. 55. 40. 27. 55. 57. 86. 126. 59. 41. 42. 60. 58. 82. 65. + 49. 48. 69. 40. 51. 51. 51. 90. 86. 35. 88. 120. 109. 153. 121. 89. + 124. 163. 185. 196. 197. 189. 187. 192. 189. 178. 181. 178. 176. + 178. 181. 181. 176. 171. 169. 174. 180. 184. 185. 184. 183. 183. + 175. 185. 189. 185. 190. 199. 188. 169. 131. 93. 74. 94. 111. 105. + 101. 107. 113. 141. 120. 119. 127. 152. 155. 191. 201. 190. 143. 77. + 40. 43. 49. 42. 42. 56. 48. 42. 59. 63. 50. 48. 56. 54. 51. 48. 47. + 47. 48. 49. 58. 49. 56. 66. 76. 112. 139. 131. 126. 129. 141. 160. + 172. 170. 167. 167. 165. 164. 163. 162. 162. 162. 162. 163. 163. + 163. 162. 161. 161. 160. 159. 159. 157. 158. 159. 160. 159. 158. + 156. 155. 156. 156. 155. 154. 154. 153. 152. 152. 109. 109. 108. + 107. 105. 103. 101. 100. 103. 101. 97. 94. 97. 109. 126. 139. 151. + 158. 166. 171. 171. 170. 170. 171. 175. 176. 174. 167. 158. 147. + 129. 114. 89. 74. 72. 79. 80. 86. 93. 90. 94. 95. 96. 97. 97. 97. + 96. 96. 98. 98. 98. 99. 101. 103. 105. 106. 110. 113. 112. 108. 105. + 102. 95. 86. 106. 202. 206. 196. 193. 193. 196. 129. 139. 129. 121. + 118. 117. 115. 117. 121. 125. 129. 133. 131. 122. 114. 115. 120. + 123. 126. 116. 109. 119. 118. 97. 79. 63. 79. 84. 79. 86. 99. 93. + 72. 57. 50. 50. 27. 57. 100. 109. 50. 37. 61. 84. 48. 51. 46. 59. + 66. 88. 79. 93. 93. 66. 104. 85. 67. 96. 108. 107. 144. 117. 123. + 161. 174. 187. 185. 185. 189. 192. 191. 185. 178. 178. 179. 180. + 179. 178. 176. 175. 174. 172. 178. 184. 185. 183. 181. 181. 183. + 191. 190. 191. 195. 198. 196. 187. 180. 141. 110. 88. 80. 89. 118. + 116. 76. 85. 128. 134. 143. 119. 148. 179. 178. 161. 100. 54. 44. + 41. 40. 45. 48. 45. 45. 52. 59. 58. 52. 53. 59. 58. 54. 48. 44. 44. + 47. 48. 49. 51. 54. 55. 63. 91. 123. 135. 129. 117. 132. 152. 165. + 168. 167. 167. 169. 163. 164. 164. 164. 164. 164. 165. 165. 163. + 163. 163. 163. 163. 162. 160. 160. 159. 159. 158. 158. 158. 157. + 157. 157. 155. 154. 154. 153. 153. 152. 152. 151. 108. 108. 108. + 107. 105. 103. 101. 100. 102. 100. 96. 93. 96. 108. 125. 138. 151. + 158. 166. 171. 171. 170. 170. 172. 175. 176. 173. 167. 158. 147. + 129. 114. 88. 73. 71. 78. 79. 85. 92. 89. 94. 95. 96. 97. 97. 97. + 97. 96. 97. 97. 98. 99. 101. 103. 104. 106. 108. 111. 111. 108. 106. + 104. 98. 89. 95. 191. 208. 204. 196. 190. 199. 153. 139. 128. 121. + 120. 114. 105. 109. 122. 129. 125. 118. 113. 111. 114. 121. 128. + 137. 127. 124. 129. 122. 99. 73. 58. 70. 72. 73. 77. 87. 93. 86. 73. + 52. 47. 51. 40. 67. 80. 86. 60. 58. 61. 74. 53. 57. 47. 52. 48. 46. + 72. 63. 44. 56. 91. 60. 66. 100. 95. 98. 127. 127. 145. 171. 175. + 179. 179. 181. 184. 185. 183. 178. 174. 175. 173. 172. 173. 174. + 174. 173. 172. 179. 177. 175. 176. 180. 185. 190. 193. 192. 191. + 192. 196. 200. 199. 193. 187. 165. 124. 96. 84. 76. 88. 100. 92. 79. + 90. 130. 133. 129. 147. 157. 149. 124. 74. 42. 44. 47. 47. 49. 49. + 49. 49. 53. 59. 57. 52. 53. 58. 56. 51. 46. 43. 44. 48. 51. 52. 52. + 52. 57. 74. 103. 128. 134. 128. 121. 135. 154. 166. 167. 165. 165. + 166. 164. 164. 164. 164. 164. 164. 164. 163. 162. 163. 163. 163. + 163. 162. 161. 160. 160. 159. 159. 159. 158. 158. 158. 157. 155. + 155. 154. 154. 153. 152. 152. 151. 108. 108. 107. 106. 105. 103. + 101. 100. 101. 99. 95. 92. 95. 107. 124. 137. 150. 157. 166. 171. + 171. 170. 171. 172. 175. 176. 173. 166. 159. 147. 130. 114. 87. 72. + 71. 77. 78. 85. 91. 88. 95. 96. 97. 97. 98. 98. 97. 97. 97. 97. 97. + 98. 100. 102. 104. 105. 107. 110. 111. 109. 108. 107. 101. 93. 84. + 178. 213. 212. 200. 192. 199. 172. 134. 125. 122. 122. 114. 103. + 110. 127. 128. 122. 114. 111. 116. 125. 132. 136. 123. 100. 114. + 138. 122. 92. 78. 70. 71. 61. 57. 68. 81. 84. 77. 70. 59. 53. 53. + 50. 75. 60. 69. 89. 91. 59. 44. 35. 41. 39. 51. 47. 40. 52. 40. 34. + 49. 71. 62. 95. 79. 70. 96. 110. 132. 152. 165. 165. 173. 177. 180. + 181. 179. 175. 172. 170. 174. 173. 172. 173. 175. 176. 175. 174. + 178. 173. 171. 175. 184. 193. 198. 198. 194. 193. 193. 197. 201. + 202. 198. 194. 183. 140. 109. 93. 68. 57. 75. 96. 88. 62. 122. 128. + 142. 148. 147. 132. 108. 64. 39. 43. 46. 44. 45. 43. 54. 53. 55. 58. + 57. 54. 54. 58. 54. 50. 44. 42. 44. 48. 52. 55. 52. 50. 62. 91. 121. + 134. 131. 125. 127. 140. 156. 166. 167. 164. 162. 162. 165. 165. + 165. 164. 163. 163. 162. 162. 162. 162. 163. 163. 163. 162. 161. + 160. 161. 160. 160. 160. 159. 159. 159. 158. 156. 155. 155. 154. + 153. 152. 151. 151. 107. 107. 106. 106. 104. 103. 101. 100. 100. 98. + 94. 90. 94. 106. 123. 136. 150. 157. 166. 171. 171. 170. 171. 173. + 174. 175. 173. 166. 159. 147. 130. 115. 88. 73. 72. 78. 79. 86. 92. + 89. 96. 96. 97. 98. 99. 99. 98. 98. 96. 96. 97. 98. 100. 102. 104. + 105. 108. 111. 112. 110. 109. 109. 103. 95. 82. 170. 218. 215. 206. + 203. 190. 162. 121. 124. 124. 121. 116. 116. 121. 125. 112. 117. + 122. 127. 133. 138. 136. 131. 128. 95. 105. 122. 97. 77. 76. 68. 61. + 52. 46. 53. 69. 79. 75. 65. 75. 71. 57. 47. 77. 54. 68. 115. 102. + 64. 41. 50. 55. 49. 57. 46. 55. 40. 46. 46. 38. 76. 107. 105. 79. + 83. 136. 135. 157. 165. 169. 178. 177. 182. 186. 184. 177. 170. 168. + 169. 170. 174. 178. 178. 174. 171. 172. 174. 168. 171. 178. 187. + 196. 199. 198. 195. 196. 194. 194. 197. 200. 200. 199. 196. 183. + 149. 120. 101. 73. 49. 55. 74. 99. 66. 99. 128. 141. 144. 154. 136. + 110. 69. 43. 41. 39. 40. 44. 45. 55. 55. 56. 57. 57. 57. 58. 60. 54. + 49. 44. 42. 44. 48. 52. 54. 50. 49. 68. 107. 135. 136. 126. 122. + 134. 144. 158. 166. 167. 165. 163. 163. 166. 165. 165. 164. 163. + 162. 161. 161. 161. 162. 163. 163. 163. 162. 161. 161. 161. 161. + 161. 160. 160. 160. 159. 159. 157. 156. 155. 154. 153. 152. 151. + 151. 106. 106. 106. 105. 104. 103. 101. 100. 100. 97. 93. 90. 93. + 105. 123. 136. 149. 156. 165. 171. 171. 171. 172. 173. 174. 175. + 173. 166. 159. 148. 131. 115. 90. 75. 73. 80. 81. 87. 94. 91. 97. + 97. 98. 99. 99. 99. 99. 99. 97. 97. 97. 98. 100. 102. 104. 105. 111. + 114. 115. 112. 111. 109. 103. 95. 88. 165. 221. 213. 212. 213. 171. + 129. 109. 122. 125. 115. 116. 129. 127. 113. 98. 114. 129. 137. 139. + 138. 130. 122. 121. 88. 82. 82. 64. 69. 82. 69. 49. 51. 45. 41. 57. + 80. 80. 64. 82. 84. 62. 41. 74. 55. 63. 106. 117. 86. 41. 44. 41. + 37. 52. 50. 45. 41. 44. 40. 55. 104. 126. 82. 108. 113. 159. 153. + 175. 175. 173. 186. 184. 188. 190. 184. 174. 166. 165. 167. 163. + 173. 181. 178. 168. 161. 164. 169. 167. 176. 188. 196. 199. 198. + 197. 196. 197. 196. 196. 197. 198. 198. 197. 196. 179. 156. 124. 98. + 79. 59. 47. 48. 88. 80. 70. 129. 132. 136. 161. 139. 97. 63. 43. 42. + 40. 43. 51. 53. 53. 54. 55. 56. 58. 61. 62. 61. 54. 50. 45. 43. 44. + 47. 49. 50. 48. 53. 79. 119. 141. 134. 123. 122. 140. 148. 157. 164. + 166. 165. 165. 166. 165. 165. 164. 163. 162. 161. 161. 160. 161. + 161. 162. 163. 163. 163. 162. 161. 161. 161. 161. 160. 160. 160. + 159. 159. 158. 157. 156. 155. 154. 152. 151. 151. 105. 105. 105. + 105. 104. 102. 101. 100. 100. 98. 93. 90. 93. 106. 123. 136. 149. + 156. 165. 170. 171. 171. 172. 174. 173. 174. 172. 166. 159. 148. + 131. 116. 90. 76. 74. 81. 82. 88. 95. 92. 97. 98. 99. 100. 100. 100. + 100. 99. 98. 98. 98. 99. 101. 103. 105. 106. 113. 116. 116. 113. + 112. 111. 105. 97. 95. 154. 218. 213. 215. 212. 145. 104. 104. 118. + 121. 110. 114. 127. 122. 104. 108. 122. 132. 133. 132. 132. 128. + 120. 106. 76. 55. 46. 48. 73. 84. 65. 42. 53. 50. 40. 51. 77. 83. + 69. 75. 84. 66. 42. 75. 56. 50. 69. 118. 120. 64. 56. 46. 36. 43. + 43. 38. 35. 26. 61. 124. 109. 97. 96. 147. 137. 144. 149. 178. 180. + 173. 184. 188. 189. 187. 179. 168. 162. 162. 164. 167. 176. 183. + 178. 166. 160. 164. 172. 177. 184. 192. 195. 195. 195. 198. 202. + 198. 199. 199. 200. 199. 199. 198. 197. 183. 167. 127. 92. 81. 67. + 47. 38. 64. 89. 59. 126. 136. 141. 166. 138. 79. 55. 46. 49. 46. 45. + 48. 47. 51. 54. 55. 56. 59. 64. 63. 60. 52. 49. 46. 45. 46. 47. 47. + 47. 50. 64. 96. 130. 141. 132. 126. 129. 146. 150. 155. 159. 161. + 162. 164. 166. 164. 164. 163. 163. 162. 161. 161. 161. 160. 161. + 162. 163. 163. 163. 162. 162. 161. 160. 160. 160. 159. 159. 159. + 158. 159. 158. 157. 155. 154. 152. 151. 151. 104. 104. 105. 104. + 104. 102. 101. 100. 101. 98. 94. 91. 94. 106. 124. 137. 148. 156. + 165. 170. 171. 171. 172. 174. 173. 174. 172. 166. 159. 148. 131. + 116. 90. 75. 74. 80. 81. 88. 94. 91. 98. 99. 99. 100. 101. 101. 100. + 100. 99. 99. 100. 101. 102. 104. 106. 107. 111. 115. 116. 114. 114. + 114. 108. 101. 97. 136. 211. 218. 215. 196. 119. 102. 104. 110. 113. + 113. 114. 117. 117. 114. 125. 130. 128. 120. 120. 126. 124. 115. + 118. 87. 52. 40. 56. 72. 60. 35. 41. 50. 52. 45. 49. 64. 75. 75. 69. + 76. 68. 51. 80. 59. 46. 50. 86. 140. 100. 97. 88. 65. 40. 24. 37. + 37. 55. 116. 159. 99. 106. 148. 174. 160. 131. 158. 187. 188. 182. + 192. 189. 187. 181. 173. 164. 160. 162. 164. 178. 180. 178. 173. + 166. 165. 172. 178. 187. 189. 191. 193. 195. 197. 200. 202. 199. + 201. 204. 205. 205. 204. 204. 204. 191. 178. 137. 100. 87. 66. 44. + 42. 47. 84. 67. 105. 144. 153. 165. 139. 69. 51. 48. 52. 47. 44. 46. + 42. 51. 55. 56. 56. 60. 64. 62. 55. 47. 46. 45. 46. 48. 49. 48. 47. + 55. 79. 115. 139. 140. 131. 132. 141. 152. 152. 153. 153. 154. 156. + 160. 162. 163. 162. 162. 162. 162. 162. 162. 162. 160. 161. 162. + 163. 163. 163. 163. 162. 160. 159. 159. 159. 158. 158. 158. 157. + 159. 159. 157. 156. 154. 152. 151. 151. 104. 104. 104. 104. 103. + 102. 101. 100. 101. 99. 95. 91. 95. 107. 124. 137. 148. 155. 165. + 170. 171. 171. 173. 174. 172. 174. 172. 166. 159. 148. 132. 117. 89. + 74. 72. 79. 80. 86. 93. 90. 98. 99. 100. 101. 101. 101. 101. 100. + 100. 100. 100. 102. 103. 105. 107. 108. 109. 113. 115. 114. 115. + 116. 111. 104. 96. 122. 205. 223. 215. 180. 104. 111. 106. 102. 108. + 119. 117. 110. 116. 133. 130. 128. 117. 106. 108. 117. 114. 101. + 106. 77. 43. 45. 79. 88. 62. 38. 42. 45. 49. 49. 47. 51. 63. 77. 69. + 70. 67. 59. 84. 63. 52. 54. 73. 136. 72. 50. 48. 45. 38. 37. 20. 57. + 123. 150. 129. 100. 164. 178. 160. 156. 115. 158. 178. 173. 171. + 186. 189. 185. 178. 169. 163. 162. 164. 166. 183. 176. 167. 161. + 161. 167. 174. 178. 189. 188. 190. 195. 201. 203. 200. 197. 200. + 203. 207. 210. 210. 210. 210. 210. 194. 185. 148. 114. 95. 63. 39. + 46. 39. 71. 73. 76. 144. 159. 160. 139. 61. 45. 44. 49. 46. 48. 54. + 53. 52. 56. 57. 56. 60. 64. 59. 51. 43. 43. 44. 47. 50. 51. 49. 47. + 59. 91. 128. 145. 140. 132. 138. 150. 155. 154. 151. 149. 149. 151. + 155. 158. 161. 161. 162. 162. 162. 162. 162. 163. 160. 160. 162. + 163. 163. 163. 163. 163. 159. 159. 158. 158. 158. 157. 157. 157. + 160. 159. 158. 156. 154. 152. 151. 150. 100. 101. 104. 105. 106. + 105. 103. 101. 99. 98. 95. 92. 94. 106. 125. 139. 148. 156. 165. + 171. 173. 173. 174. 176. 177. 173. 174. 170. 157. 148. 135. 114. 92. + 76. 72. 77. 79. 86. 95. 93. 95. 97. 100. 102. 103. 102. 101. 100. + 97. 99. 104. 106. 101. 96. 100. 109. 142. 122. 110. 113. 117. 112. + 109. 111. 100. 98. 187. 224. 210. 151. 121. 104. 116. 121. 114. 100. + 102. 120. 131. 128. 132. 120. 105. 94. 63. 92. 81. 64. 78. 81. 59. + 43. 94. 77. 44. 33. 41. 50. 59. 52. 40. 48. 60. 56. 75. 57. 56. 62. + 85. 66. 65. 54. 63. 129. 81. 46. 18. 54. 32. 25. 44. 108. 155. 127. + 105. 162. 197. 160. 159. 173. 134. 150. 168. 155. 180. 189. 183. + 176. 170. 168. 165. 164. 168. 175. 176. 161. 153. 162. 170. 171. + 175. 184. 187. 190. 196. 199. 200. 200. 201. 202. 201. 202. 204. + 206. 207. 209. 209. 209. 202. 189. 161. 126. 95. 72. 53. 40. 38. 50. + 75. 70. 117. 157. 171. 152. 66. 47. 54. 51. 49. 59. 56. 57. 49. 52. + 56. 61. 64. 62. 57. 53. 42. 51. 51. 50. 56. 52. 44. 47. 65. 104. + 139. 144. 131. 128. 142. 157. 159. 156. 153. 150. 148. 148. 149. + 150. 153. 154. 155. 157. 158. 160. 161. 162. 165. 164. 163. 161. + 160. 160. 160. 160. 159. 159. 159. 158. 158. 157. 157. 157. 157. + 157. 156. 156. 154. 152. 151. 150. 102. 102. 104. 104. 104. 103. + 102. 101. 99. 99. 96. 93. 94. 106. 125. 140. 148. 156. 165. 171. + 173. 173. 174. 176. 177. 173. 174. 170. 157. 148. 135. 114. 92. 76. + 73. 78. 80. 87. 96. 94. 97. 99. 101. 103. 104. 103. 102. 101. 103. + 101. 100. 99. 98. 101. 115. 130. 134. 119. 110. 114. 117. 112. 110. + 113. 102. 103. 155. 213. 219. 143. 118. 107. 119. 119. 113. 107. + 111. 124. 130. 128. 126. 114. 98. 95. 77. 92. 70. 49. 63. 56. 51. + 53. 106. 66. 42. 49. 59. 56. 58. 56. 47. 48. 54. 54. 55. 66. 61. 50. + 85. 92. 93. 62. 43. 93. 82. 40. 35. 36. 26. 46. 105. 140. 134. 120. + 151. 176. 172. 171. 163. 171. 132. 150. 177. 168. 186. 186. 189. + 178. 170. 171. 173. 172. 170. 169. 160. 155. 157. 167. 172. 172. + 180. 192. 187. 190. 195. 197. 198. 199. 201. 202. 202. 203. 205. + 207. 208. 209. 210. 210. 205. 194. 170. 136. 104. 79. 57. 41. 31. + 46. 57. 73. 93. 157. 165. 145. 78. 54. 56. 51. 49. 58. 53. 53. 55. + 56. 59. 63. 65. 63. 57. 51. 42. 45. 43. 48. 57. 51. 42. 46. 77. 114. + 143. 142. 130. 133. 148. 160. 158. 157. 154. 151. 149. 148. 148. + 148. 150. 151. 152. 153. 155. 156. 157. 158. 160. 159. 159. 159. + 160. 161. 162. 162. 161. 161. 160. 159. 158. 157. 156. 155. 156. + 156. 156. 155. 154. 152. 151. 150. 104. 104. 104. 103. 102. 102. + 101. 101. 99. 98. 96. 92. 94. 106. 125. 140. 148. 156. 165. 171. + 173. 173. 174. 176. 177. 173. 174. 170. 157. 148. 135. 114. 93. 78. + 75. 80. 81. 89. 97. 95. 99. 100. 102. 104. 105. 105. 104. 103. 105. + 101. 98. 97. 98. 105. 122. 139. 124. 115. 112. 116. 117. 113. 113. + 117. 107. 109. 118. 188. 227. 147. 115. 114. 117. 115. 113. 115. + 121. 126. 129. 128. 139. 133. 114. 112. 93. 85. 61. 49. 58. 37. 44. + 52. 104. 47. 34. 53. 68. 59. 55. 56. 53. 49. 49. 52. 46. 67. 54. 45. + 94. 106. 108. 77. 58. 87. 120. 53. 42. 18. 41. 97. 149. 143. 125. + 142. 182. 181. 165. 179. 167. 176. 141. 152. 177. 173. 188. 190. + 191. 176. 165. 167. 173. 170. 160. 153. 149. 153. 164. 174. 174. + 172. 182. 196. 189. 191. 194. 196. 197. 198. 201. 203. 202. 204. + 205. 207. 209. 210. 211. 211. 208. 200. 178. 146. 113. 84. 59. 42. + 31. 47. 44. 80. 73. 159. 168. 144. 91. 61. 57. 50. 49. 58. 51. 50. + 61. 60. 60. 64. 67. 65. 57. 49. 46. 42. 40. 50. 60. 49. 42. 52. 96. + 128. 148. 139. 130. 141. 157. 163. 159. 158. 156. 154. 152. 150. + 149. 148. 147. 148. 148. 149. 150. 151. 152. 152. 152. 153. 154. + 155. 157. 160. 162. 163. 162. 161. 160. 159. 157. 156. 155. 154. + 156. 156. 156. 155. 154. 152. 151. 150. 106. 105. 104. 102. 101. + 100. 100. 100. 98. 97. 94. 91. 93. 105. 123. 138. 148. 156. 165. + 171. 173. 173. 174. 176. 177. 173. 174. 170. 157. 148. 135. 114. 94. + 78. 76. 82. 83. 90. 98. 95. 99. 100. 102. 103. 104. 104. 104. 103. + 100. 99. 100. 103. 103. 105. 115. 126. 115. 113. 114. 119. 119. 115. + 116. 121. 115. 111. 101. 154. 219. 171. 115. 121. 110. 110. 116. + 124. 127. 125. 126. 131. 127. 125. 105. 98. 76. 55. 54. 59. 56. 36. + 42. 37. 93. 52. 48. 51. 57. 59. 54. 50. 53. 51. 48. 51. 58. 59. 37. + 52. 103. 88. 94. 85. 74. 87. 151. 72. 24. 25. 85. 144. 138. 118. + 143. 179. 176. 175. 184. 178. 171. 183. 154. 151. 167. 168. 186. + 198. 190. 175. 163. 163. 166. 161. 151. 144. 154. 159. 169. 176. + 175. 172. 180. 192. 192. 193. 195. 196. 197. 199. 202. 205. 203. + 204. 206. 208. 210. 211. 211. 212. 210. 203. 183. 151. 117. 87. 62. + 45. 36. 44. 41. 77. 66. 149. 176. 146. 98. 62. 53. 48. 49. 59. 52. + 51. 63. 60. 59. 63. 66. 64. 56. 48. 50. 46. 45. 56. 60. 46. 45. 67. + 115. 139. 149. 135. 131. 148. 163. 165. 161. 161. 160. 158. 156. + 154. 152. 150. 147. 148. 148. 148. 148. 149. 149. 149. 147. 148. + 148. 150. 152. 155. 157. 159. 159. 158. 158. 157. 156. 156. 155. + 155. 155. 155. 155. 155. 154. 152. 151. 150. 107. 105. 104. 102. + 100. 99. 99. 99. 96. 95. 92. 89. 91. 103. 122. 136. 148. 156. 165. + 171. 173. 173. 174. 176. 177. 173. 174. 170. 157. 148. 135. 114. 93. + 78. 77. 83. 84. 91. 98. 95. 99. 100. 101. 102. 102. 103. 103. 103. + 100. 99. 102. 105. 105. 105. 110. 118. 112. 114. 117. 121. 120. 117. + 118. 122. 122. 109. 108. 125. 191. 196. 115. 124. 107. 114. 125. + 133. 131. 126. 127. 134. 114. 100. 74. 70. 61. 48. 76. 82. 43. 41. + 45. 29. 83. 79. 75. 50. 47. 64. 58. 46. 50. 52. 50. 54. 68. 60. 33. + 55. 92. 62. 77. 70. 52. 56. 130. 82. 19. 71. 128. 143. 115. 127. + 165. 182. 167. 177. 193. 180. 182. 184. 150. 139. 161. 176. 189. + 197. 182. 172. 164. 162. 161. 157. 155. 155. 165. 165. 169. 173. + 175. 176. 181. 187. 194. 195. 197. 198. 198. 200. 203. 206. 203. + 204. 206. 208. 210. 211. 211. 212. 213. 207. 188. 156. 122. 92. 68. + 53. 40. 37. 42. 61. 70. 124. 179. 149. 99. 59. 49. 46. 49. 60. 55. + 56. 60. 58. 58. 60. 64. 62. 55. 49. 50. 52. 53. 58. 54. 41. 52. 86. + 129. 143. 145. 133. 134. 153. 166. 165. 163. 163. 163. 162. 160. + 158. 156. 155. 151. 151. 151. 151. 150. 150. 150. 150. 146. 145. + 146. 146. 147. 149. 150. 151. 152. 152. 153. 153. 154. 155. 155. + 156. 154. 154. 154. 154. 153. 152. 151. 150. 105. 104. 103. 102. + 101. 99. 98. 98. 96. 95. 92. 89. 91. 103. 121. 136. 148. 156. 165. + 171. 173. 173. 174. 176. 177. 173. 174. 170. 157. 148. 135. 114. 93. + 78. 77. 83. 84. 91. 97. 94. 99. 100. 100. 101. 102. 103. 103. 104. + 105. 102. 100. 102. 104. 106. 114. 123. 113. 115. 118. 119. 119. + 117. 117. 118. 122. 109. 123. 114. 150. 189. 114. 121. 114. 124. + 134. 137. 133. 129. 128. 130. 115. 83. 54. 56. 56. 53. 98. 82. 35. + 49. 49. 33. 65. 82. 74. 41. 58. 72. 60. 45. 51. 51. 49. 64. 60. 69. + 45. 50. 66. 51. 83. 49. 33. 33. 89. 98. 64. 125. 142. 117. 126. 168. + 170. 155. 174. 188. 183. 188. 190. 179. 140. 129. 166. 193. 189. + 184. 165. 160. 158. 158. 156. 155. 159. 166. 170. 168. 168. 171. + 175. 180. 184. 186. 193. 195. 198. 199. 199. 200. 202. 204. 202. + 204. 205. 207. 209. 210. 211. 211. 215. 212. 196. 165. 131. 102. 78. + 64. 46. 38. 45. 52. 80. 103. 179. 160. 99. 58. 48. 47. 50. 59. 56. + 60. 58. 58. 59. 60. 60. 57. 53. 49. 47. 54. 56. 53. 46. 41. 64. 105. + 138. 141. 138. 134. 141. 157. 165. 164. 164. 163. 163. 162. 161. + 160. 160. 160. 157. 157. 156. 155. 154. 153. 152. 152. 147. 146. + 145. 144. 144. 144. 145. 145. 146. 147. 148. 149. 151. 152. 153. + 154. 153. 153. 153. 153. 153. 152. 151. 150. 102. 103. 103. 103. + 102. 100. 98. 97. 97. 96. 94. 90. 92. 104. 123. 138. 148. 156. 165. + 171. 173. 173. 174. 176. 177. 173. 174. 170. 157. 148. 135. 114. 92. + 77. 76. 83. 84. 90. 96. 93. 101. 101. 101. 102. 103. 104. 105. 105. + 107. 103. 101. 102. 104. 106. 113. 121. 115. 116. 116. 116. 116. + 115. 114. 111. 114. 111. 132. 121. 110. 149. 112. 112. 125. 133. + 136. 132. 131. 131. 124. 114. 91. 61. 50. 54. 41. 36. 94. 59. 45. + 56. 50. 46. 43. 59. 58. 57. 79. 73. 48. 43. 57. 46. 46. 80. 49. 69. + 56. 52. 50. 50. 102. 49. 32. 34. 57. 103. 120. 139. 129. 125. 157. + 178. 162. 147. 171. 185. 181. 190. 187. 181. 152. 137. 170. 195. + 180. 171. 154. 152. 153. 157. 157. 156. 160. 166. 171. 172. 172. + 173. 176. 181. 184. 184. 190. 193. 197. 198. 198. 198. 199. 200. + 202. 203. 205. 207. 208. 209. 210. 210. 213. 213. 201. 174. 141. + 110. 86. 70. 48. 43. 41. 49. 83. 89. 170. 172. 103. 62. 53. 51. 51. + 57. 54. 61. 59. 61. 63. 61. 57. 52. 50. 49. 46. 57. 55. 46. 43. 51. + 82. 123. 142. 136. 132. 138. 150. 160. 164. 164. 163. 162. 161. 160. + 160. 161. 162. 163. 162. 161. 160. 159. 157. 156. 155. 154. 148. + 148. 146. 145. 144. 144. 144. 145. 143. 143. 144. 145. 146. 147. + 148. 149. 152. 153. 153. 153. 153. 152. 151. 150. 100. 102. 103. + 104. 103. 101. 98. 96. 99. 98. 95. 92. 94. 106. 125. 139. 148. 156. + 165. 171. 173. 173. 174. 176. 177. 173. 174. 170. 157. 148. 135. + 114. 91. 77. 76. 83. 84. 90. 96. 92. 103. 103. 103. 103. 104. 105. + 106. 107. 105. 102. 103. 106. 107. 105. 107. 111. 117. 116. 114. + 113. 113. 113. 110. 106. 107. 114. 132. 131. 86. 110. 110. 105. 132. + 137. 133. 125. 126. 131. 118. 98. 66. 55. 70. 77. 44. 33. 105. 67. + 57. 59. 47. 59. 32. 45. 61. 100. 94. 67. 33. 40. 61. 42. 43. 93. 44. + 60. 57. 61. 50. 50. 116. 63. 25. 34. 31. 88. 144. 118. 111. 159. + 178. 153. 157. 164. 156. 171. 193. 186. 177. 188. 176. 153. 169. + 182. 166. 164. 159. 156. 158. 163. 165. 163. 162. 164. 172. 176. + 178. 177. 176. 178. 180. 180. 187. 191. 195. 197. 197. 197. 197. + 197. 201. 202. 204. 206. 207. 209. 209. 209. 208. 211. 203. 179. + 146. 115. 88. 71. 42. 43. 30. 45. 77. 78. 155. 174. 108. 68. 58. 55. + 51. 55. 51. 59. 60. 64. 67. 63. 55. 49. 47. 48. 48. 59. 54. 42. 45. + 62. 97. 135. 145. 132. 129. 141. 156. 162. 163. 164. 161. 160. 158. + 157. 158. 160. 162. 164. 164. 163. 162. 160. 159. 157. 156. 155. + 150. 149. 148. 147. 146. 146. 146. 146. 142. 143. 143. 143. 144. + 144. 144. 144. 152. 152. 153. 153. 153. 152. 151. 151. 102. 102. + 102. 101. 100. 99. 98. 97. 95. 96. 94. 90. 90. 103. 123. 140. 150. + 155. 163. 169. 172. 174. 176. 177. 176. 172. 175. 171. 158. 148. + 134. 113. 91. 79. 73. 79. 84. 86. 91. 98. 98. 100. 102. 103. 103. + 102. 103. 105. 101. 102. 104. 104. 105. 107. 111. 114. 113. 118. + 125. 119. 114. 124. 129. 117. 129. 112. 150. 101. 114. 145. 167. + 117. 117. 126. 125. 134. 122. 119. 132. 100. 53. 60. 107. 53. 34. + 38. 92. 86. 58. 43. 55. 46. 63. 77. 102. 80. 73. 47. 37. 51. 53. 43. + 58. 88. 37. 56. 113. 50. 48. 78. 64. 43. 38. 45. 72. 124. 107. 92. + 152. 176. 158. 167. 164. 151. 156. 178. 191. 187. 167. 204. 176. + 161. 176. 171. 168. 155. 149. 161. 169. 165. 162. 166. 170. 171. + 175. 173. 176. 181. 177. 169. 173. 184. 185. 188. 192. 196. 198. + 197. 196. 195. 200. 200. 202. 204. 207. 210. 212. 212. 207. 211. + 208. 187. 154. 119. 91. 76. 47. 42. 45. 38. 63. 79. 144. 178. 131. + 57. 71. 52. 63. 65. 56. 63. 56. 66. 69. 60. 51. 51. 55. 56. 53. 53. + 49. 44. 47. 70. 108. 139. 142. 130. 129. 143. 155. 157. 160. 166. + 162. 162. 162. 161. 161. 161. 160. 160. 164. 165. 165. 165. 163. + 161. 158. 157. 156. 155. 153. 151. 148. 146. 144. 143. 142. 142. + 143. 144. 144. 143. 142. 142. 146. 146. 147. 148. 149. 150. 151. + 151. 102. 102. 102. 101. 100. 99. 98. 97. 97. 97. 95. 90. 91. 102. + 123. 139. 150. 155. 163. 169. 172. 174. 176. 177. 176. 172. 175. + 171. 158. 148. 135. 113. 90. 79. 73. 80. 85. 86. 90. 98. 98. 100. + 102. 103. 102. 102. 103. 105. 102. 103. 104. 104. 105. 107. 111. + 114. 116. 113. 114. 121. 125. 121. 119. 124. 120. 132. 167. 101. + 124. 157. 163. 132. 120. 133. 127. 133. 127. 115. 106. 66. 54. 69. + 99. 47. 34. 47. 107. 88. 41. 37. 53. 50. 72. 78. 91. 75. 57. 46. 41. + 45. 47. 47. 54. 66. 33. 54. 91. 53. 51. 85. 60. 53. 45. 42. 138. + 139. 83. 146. 193. 158. 172. 180. 174. 158. 157. 174. 186. 185. 194. + 192. 175. 198. 191. 131. 115. 129. 140. 150. 158. 159. 161. 167. + 169. 167. 173. 173. 177. 181. 181. 178. 180. 184. 184. 187. 191. + 195. 196. 196. 194. 193. 195. 199. 203. 205. 205. 206. 209. 211. + 214. 216. 211. 190. 154. 112. 75. 53. 46. 40. 43. 39. 62. 74. 136. + 180. 137. 70. 68. 53. 63. 62. 58. 59. 62. 69. 70. 60. 50. 48. 51. + 51. 50. 52. 49. 45. 54. 83. 118. 140. 138. 130. 132. 146. 158. 159. + 160. 165. 162. 162. 161. 161. 160. 160. 160. 160. 163. 164. 164. + 164. 163. 160. 158. 157. 156. 155. 154. 152. 150. 148. 146. 146. + 144. 144. 145. 145. 144. 143. 142. 142. 142. 142. 143. 144. 144. + 145. 145. 146. 101. 102. 102. 102. 101. 100. 98. 98. 100. 99. 97. + 91. 91. 102. 122. 138. 149. 155. 163. 169. 173. 174. 176. 177. 176. + 173. 175. 171. 158. 149. 135. 114. 89. 78. 74. 81. 87. 87. 90. 97. + 98. 100. 103. 103. 102. 102. 103. 104. 102. 103. 104. 105. 105. 108. + 111. 115. 116. 115. 112. 123. 130. 112. 118. 159. 193. 149. 128. 49. + 55. 55. 72. 124. 128. 140. 122. 115. 121. 112. 92. 59. 67. 87. 85. + 38. 38. 59. 121. 81. 37. 42. 50. 47. 67. 62. 61. 56. 42. 47. 47. 43. + 46. 56. 60. 56. 39. 67. 92. 50. 66. 78. 52. 40. 48. 100. 147. 111. + 118. 184. 182. 160. 178. 181. 173. 158. 158. 175. 190. 193. 191. + 191. 173. 156. 118. 78. 84. 97. 122. 126. 131. 135. 145. 158. 169. + 172. 176. 179. 179. 176. 176. 179. 179. 176. 182. 185. 189. 193. + 195. 194. 192. 190. 196. 198. 200. 200. 199. 200. 204. 208. 202. + 198. 189. 171. 142. 106. 71. 50. 45. 37. 41. 41. 59. 67. 122. 183. + 145. 89. 63. 54. 64. 60. 62. 55. 65. 69. 68. 59. 50. 48. 49. 50. 49. + 53. 49. 46. 64. 101. 131. 141. 133. 130. 136. 152. 161. 160. 159. + 162. 161. 161. 160. 160. 160. 159. 159. 159. 162. 162. 163. 163. + 162. 160. 158. 156. 155. 155. 154. 153. 152. 151. 150. 149. 148. + 148. 147. 147. 146. 144. 143. 142. 140. 140. 140. 140. 140. 140. + 140. 140. 101. 102. 102. 102. 101. 100. 99. 99. 101. 101. 98. 92. + 91. 102. 121. 137. 149. 155. 163. 170. 173. 175. 175. 176. 177. 173. + 176. 172. 158. 149. 135. 114. 88. 78. 75. 83. 88. 88. 90. 96. 99. + 101. 103. 103. 102. 102. 103. 104. 102. 103. 104. 105. 105. 107. + 111. 115. 113. 125. 120. 120. 124. 108. 129. 195. 160. 85. 68. 33. + 37. 27. 60. 143. 176. 173. 130. 95. 93. 84. 62. 48. 88. 101. 66. 32. + 49. 74. 126. 69. 42. 50. 46. 46. 61. 51. 45. 56. 40. 48. 51. 46. 49. + 60. 70. 72. 45. 76. 96. 44. 75. 53. 44. 32. 86. 151. 103. 102. 175. + 177. 162. 174. 187. 178. 162. 151. 159. 179. 194. 197. 198. 192. + 160. 114. 86. 99. 117. 107. 103. 100. 95. 93. 101. 119. 140. 153. + 171. 181. 183. 176. 172. 176. 176. 171. 179. 182. 187. 191. 193. + 192. 189. 187. 195. 194. 195. 197. 201. 205. 208. 209. 210. 192. + 169. 145. 119. 88. 60. 44. 46. 37. 40. 43. 55. 62. 106. 184. 150. + 105. 59. 54. 64. 61. 66. 55. 64. 65. 62. 56. 51. 49. 51. 53. 52. 55. + 49. 46. 72. 116. 140. 140. 129. 131. 142. 157. 164. 162. 159. 159. + 160. 160. 159. 159. 158. 158. 158. 158. 160. 160. 161. 162. 161. + 159. 158. 156. 155. 155. 154. 154. 154. 153. 153. 153. 151. 151. + 151. 149. 148. 146. 144. 143. 141. 141. 140. 140. 139. 138. 138. + 137. 101. 102. 102. 102. 102. 101. 100. 100. 101. 101. 98. 92. 90. + 101. 120. 136. 148. 155. 163. 171. 174. 175. 175. 175. 177. 174. + 176. 172. 159. 150. 136. 115. 89. 79. 76. 83. 89. 88. 90. 96. 99. + 101. 103. 103. 102. 101. 102. 103. 101. 102. 103. 104. 104. 107. + 111. 114. 110. 127. 119. 114. 124. 120. 136. 184. 143. 77. 68. 50. + 40. 57. 111. 152. 169. 158. 120. 81. 76. 70. 55. 61. 95. 92. 45. 36. + 67. 87. 122. 72. 35. 45. 44. 58. 69. 61. 55. 78. 54. 50. 47. 47. 46. + 50. 67. 86. 60. 78. 66. 60. 62. 33. 38. 71. 144. 123. 106. 154. 175. + 164. 184. 180. 202. 180. 156. 152. 168. 188. 195. 192. 194. 148. + 126. 133. 144. 149. 142. 136. 114. 106. 91. 77. 68. 72. 86. 100. + 130. 152. 171. 176. 176. 179. 178. 173. 176. 179. 185. 190. 192. + 191. 188. 186. 189. 189. 193. 200. 206. 204. 193. 183. 155. 135. + 115. 104. 93. 77. 61. 53. 49. 40. 41. 43. 51. 61. 92. 182. 153. 116. + 60. 52. 62. 66. 66. 59. 66. 63. 58. 54. 51. 49. 51. 54. 57. 56. 48. + 49. 80. 125. 143. 136. 128. 134. 148. 160. 165. 162. 158. 158. 158. + 158. 158. 158. 157. 157. 156. 156. 157. 158. 159. 160. 160. 159. + 157. 156. 154. 154. 155. 155. 155. 155. 155. 155. 154. 154. 153. + 152. 150. 148. 146. 144. 142. 142. 140. 139. 137. 136. 134. 134. + 101. 101. 102. 102. 102. 102. 101. 101. 100. 100. 96. 91. 89. 100. + 120. 136. 148. 154. 164. 171. 174. 175. 175. 175. 178. 174. 176. + 173. 159. 150. 136. 115. 90. 79. 76. 83. 88. 88. 91. 98. 100. 102. + 104. 104. 102. 101. 102. 103. 100. 101. 102. 102. 103. 105. 109. + 112. 110. 118. 111. 115. 138. 142. 136. 142. 181. 104. 60. 54. 24. + 28. 102. 131. 119. 102. 91. 75. 73. 74. 68. 87. 85. 70. 38. 54. 82. + 85. 106. 94. 32. 38. 46. 73. 70. 60. 53. 77. 76. 55. 41. 42. 39. 36. + 52. 76. 89. 93. 38. 88. 41. 31. 47. 125. 149. 101. 156. 183. 158. + 175. 188. 191. 198. 173. 154. 162. 186. 199. 192. 180. 143. 117. + 125. 149. 162. 151. 137. 156. 156. 143. 125. 104. 84. 68. 64. 67. + 76. 103. 137. 161. 173. 177. 174. 170. 172. 177. 183. 190. 192. 192. + 189. 187. 190. 191. 192. 193. 186. 166. 140. 120. 94. 84. 82. 93. + 102. 98. 91. 88. 53. 47. 44. 41. 48. 65. 82. 177. 154. 121. 67. 51. + 57. 74. 61. 64. 71. 63. 55. 52. 50. 48. 48. 51. 59. 55. 49. 58. 92. + 130. 142. 133. 129. 139. 153. 162. 164. 161. 158. 157. 157. 157. + 157. 156. 156. 156. 155. 155. 155. 156. 158. 159. 159. 158. 157. + 156. 154. 154. 155. 155. 155. 155. 155. 155. 156. 156. 155. 154. + 152. 150. 148. 147. 143. 142. 140. 138. 135. 133. 131. 130. 101. + 101. 102. 103. 103. 102. 102. 101. 98. 98. 95. 89. 88. 99. 119. 135. + 147. 154. 164. 172. 175. 175. 175. 174. 178. 174. 177. 173. 159. + 150. 136. 115. 92. 80. 75. 81. 87. 88. 92. 99. 100. 102. 104. 104. + 102. 101. 101. 102. 98. 99. 101. 101. 101. 104. 108. 111. 111. 109. + 113. 131. 151. 154. 142. 131. 140. 105. 58. 93. 77. 44. 105. 127. + 128. 88. 82. 73. 62. 63. 66. 92. 76. 57. 54. 83. 87. 61. 71. 112. + 45. 40. 48. 80. 56. 45. 42. 63. 94. 64. 39. 37. 40. 37. 43. 54. 79. + 97. 45. 76. 32. 43. 91. 140. 123. 140. 181. 172. 168. 185. 179. 201. + 183. 165. 158. 176. 195. 190. 163. 140. 110. 122. 140. 133. 134. + 129. 116. 147. 166. 149. 131. 120. 110. 97. 86. 82. 73. 85. 110. + 139. 159. 165. 165. 165. 169. 174. 182. 189. 193. 193. 190. 188. + 192. 190. 183. 170. 148. 124. 102. 89. 114. 104. 104. 116. 120. 110. + 97. 93. 57. 55. 48. 39. 45. 70. 76. 172. 156. 123. 77. 49. 51. 80. + 51. 68. 72. 60. 51. 50. 50. 48. 49. 53. 57. 51. 51. 71. 107. 136. + 140. 130. 132. 144. 156. 162. 161. 159. 158. 158. 156. 156. 156. + 156. 155. 155. 154. 154. 153. 154. 156. 158. 158. 158. 157. 156. + 155. 155. 154. 154. 154. 154. 154. 154. 157. 157. 157. 156. 154. + 153. 151. 150. 147. 145. 143. 140. 137. 134. 132. 131. 101. 101. + 102. 103. 103. 103. 102. 102. 96. 96. 93. 88. 88. 99. 119. 135. 147. + 154. 164. 172. 175. 175. 175. 174. 178. 174. 177. 173. 160. 150. + 137. 115. 93. 81. 75. 81. 86. 88. 93. 101. 100. 102. 104. 104. 102. + 101. 101. 102. 97. 98. 100. 100. 100. 103. 107. 110. 112. 107. 124. + 149. 156. 154. 155. 152. 155. 190. 128. 140. 129. 91. 129. 117. 146. + 82. 71. 64. 51. 63. 81. 117. 76. 56. 75. 107. 85. 34. 39. 117. 61. + 45. 49. 80. 45. 38. 43. 67. 104. 72. 42. 37. 46. 49. 44. 40. 32. 76. + 62. 32. 32. 53. 141. 125. 123. 182. 174. 171. 182. 181. 199. 196. + 181. 168. 168. 185. 192. 166. 121. 88. 110. 105. 108. 103. 119. 106. + 69. 96. 136. 115. 99. 101. 111. 113. 109. 106. 111. 102. 106. 128. + 148. 156. 160. 165. 168. 173. 182. 189. 194. 194. 191. 189. 188. + 184. 171. 149. 126. 111. 109. 113. 105. 94. 92. 100. 101. 88. 76. + 73. 60. 60. 51. 38. 44. 74. 73. 168. 157. 124. 84. 49. 48. 83. 43. + 68. 68. 56. 47. 48. 51. 51. 53. 57. 54. 48. 54. 82. 118. 140. 139. + 129. 135. 146. 158. 162. 159. 157. 157. 158. 156. 156. 155. 155. + 155. 154. 154. 154. 152. 154. 155. 157. 158. 158. 157. 156. 155. + 155. 154. 154. 154. 153. 153. 153. 157. 157. 157. 157. 155. 154. + 152. 151. 151. 150. 147. 144. 141. 137. 135. 134. 99. 102. 103. 100. + 99. 102. 101. 97. 97. 96. 91. 85. 84. 96. 118. 135. 146. 155. 165. + 173. 175. 175. 177. 178. 178. 174. 175. 171. 158. 151. 139. 118. 92. + 77. 75. 81. 83. 90. 97. 95. 99. 100. 102. 104. 104. 102. 100. 99. + 99. 106. 94. 89. 118. 95. 106. 107. 125. 138. 142. 143. 152. 156. + 156. 161. 166. 163. 163. 167. 155. 118. 83. 70. 65. 46. 56. 64. 61. + 92. 114. 88. 63. 78. 76. 114. 60. 37. 34. 80. 90. 36. 46. 87. 47. + 40. 39. 55. 86. 102. 65. 31. 49. 52. 38. 50. 37. 49. 47. 46. 37. + 113. 141. 106. 168. 172. 173. 174. 183. 197. 202. 198. 182. 173. + 193. 198. 145. 94. 84. 89. 81. 103. 72. 50. 72. 60. 40. 67. 84. 54. + 53. 52. 83. 120. 113. 119. 121. 119. 120. 127. 138. 149. 156. 159. + 155. 176. 180. 184. 203. 201. 189. 192. 190. 173. 173. 136. 129. + 119. 66. 79. 60. 52. 50. 59. 66. 66. 65. 67. 70. 55. 44. 32. 47. 75. + 71. 168. 168. 111. 98. 58. 50. 70. 57. 66. 64. 56. 49. 49. 49. 49. + 52. 56. 51. 40. 55. 100. 136. 142. 134. 130. 141. 151. 159. 161. + 159. 159. 156. 152. 155. 155. 155. 155. 155. 155. 155. 155. 155. + 156. 156. 157. 157. 156. 156. 155. 152. 152. 152. 152. 153. 154. + 155. 156. 156. 157. 157. 157. 155. 151. 148. 146. 146. 146. 145. + 143. 141. 139. 137. 136. 97. 101. 101. 98. 98. 100. 99. 96. 96. 94. + 90. 83. 83. 95. 117. 134. 146. 155. 165. 173. 175. 175. 177. 178. + 178. 174. 175. 171. 158. 150. 138. 118. 93. 78. 75. 81. 81. 87. 94. + 92. 98. 99. 101. 102. 102. 101. 99. 98. 102. 95. 90. 95. 104. 84. + 111. 156. 149. 156. 152. 139. 143. 159. 155. 134. 144. 143. 119. + 119. 136. 97. 39. 28. 28. 45. 88. 93. 75. 108. 123. 71. 65. 81. 86. + 118. 61. 39. 38. 83. 65. 52. 49. 100. 38. 45. 33. 39. 59. 106. 98. + 52. 38. 40. 39. 46. 42. 34. 43. 23. 78. 137. 123. 134. 183. 179. + 177. 180. 191. 199. 197. 191. 186. 187. 184. 145. 90. 73. 77. 68. + 62. 50. 55. 59. 50. 54. 58. 43. 52. 38. 45. 48. 50. 65. 101. 152. + 128. 125. 124. 127. 135. 144. 151. 154. 160. 172. 182. 190. 197. + 193. 193. 202. 193. 189. 124. 87. 73. 62. 69. 45. 45. 46. 52. 59. + 60. 57. 60. 66. 61. 50. 44. 34. 47. 72. 65. 161. 171. 116. 98. 63. + 54. 73. 59. 67. 62. 54. 48. 49. 49. 49. 52. 56. 48. 39. 58. 105. + 138. 139. 131. 131. 145. 154. 160. 160. 158. 158. 156. 153. 155. + 155. 155. 155. 155. 155. 155. 155. 155. 155. 156. 157. 157. 156. + 155. 155. 152. 152. 152. 153. 153. 153. 153. 153. 154. 155. 155. + 154. 152. 149. 146. 144. 145. 145. 144. 143. 140. 138. 135. 134. 96. + 99. 99. 96. 96. 98. 97. 93. 94. 92. 87. 81. 80. 93. 115. 133. 146. + 155. 165. 173. 175. 175. 177. 178. 178. 173. 175. 170. 157. 149. + 137. 117. 93. 78. 75. 80. 80. 85. 92. 89. 97. 98. 99. 100. 100. 99. + 98. 97. 89. 102. 105. 93. 87. 118. 143. 172. 221. 150. 126. 152. + 156. 143. 153. 169. 150. 141. 83. 61. 92. 71. 31. 46. 47. 97. 91. + 72. 98. 101. 78. 83. 73. 86. 98. 119. 60. 41. 42. 82. 46. 75. 53. + 114. 37. 53. 37. 35. 40. 75. 108. 108. 76. 42. 36. 50. 48. 34. 34. + 47. 137. 136. 130. 182. 181. 171. 168. 180. 195. 200. 195. 188. 199. + 183. 148. 93. 54. 56. 62. 47. 45. 51. 47. 44. 48. 48. 50. 61. 96. + 83. 58. 45. 29. 29. 72. 109. 134. 131. 128. 129. 134. 141. 147. 150. + 163. 167. 184. 197. 195. 196. 204. 207. 178. 113. 83. 60. 48. 49. + 44. 65. 66. 57. 49. 49. 52. 55. 57. 60. 50. 45. 46. 38. 48. 68. 58. + 153. 172. 119. 95. 68. 57. 75. 60. 66. 58. 51. 47. 48. 50. 49. 51. + 55. 47. 42. 67. 117. 144. 137. 130. 136. 151. 157. 160. 158. 157. + 158. 157. 153. 154. 154. 154. 154. 154. 154. 154. 154. 154. 155. + 156. 156. 156. 156. 155. 154. 152. 152. 153. 154. 154. 152. 151. + 150. 152. 152. 152. 151. 149. 146. 143. 141. 141. 141. 142. 142. + 140. 138. 136. 134. 94. 98. 98. 95. 94. 96. 95. 91. 92. 90. 85. 78. + 78. 91. 114. 132. 146. 155. 165. 173. 175. 175. 177. 178. 178. 173. + 175. 170. 157. 148. 136. 116. 91. 76. 73. 79. 79. 86. 92. 90. 96. + 97. 98. 99. 99. 98. 97. 96. 91. 101. 98. 83. 83. 162. 184. 188. 179. + 135. 129. 149. 153. 159. 149. 114. 127. 120. 80. 55. 62. 45. 27. 44. + 103. 111. 64. 57. 101. 70. 38. 91. 89. 90. 105. 111. 54. 43. 43. 73. + 39. 79. 50. 109. 54. 54. 45. 40. 37. 44. 82. 110. 93. 67. 56. 49. + 34. 32. 21. 102. 148. 99. 153. 192. 176. 167. 167. 182. 196. 199. + 195. 192. 198. 147. 96. 72. 61. 52. 47. 45. 52. 64. 53. 39. 44. 44. + 59. 94. 164. 165. 113. 73. 43. 35. 63. 57. 129. 129. 129. 131. 136. + 141. 145. 148. 159. 163. 185. 199. 200. 212. 211. 186. 118. 40. 54. + 52. 51. 74. 70. 115. 127. 91. 52. 38. 47. 59. 58. 51. 46. 44. 48. + 41. 49. 67. 56. 151. 172. 122. 89. 73. 59. 76. 59. 61. 54. 49. 46. + 49. 51. 50. 50. 53. 49. 52. 83. 131. 151. 138. 133. 145. 157. 160. + 161. 157. 156. 157. 157. 153. 153. 153. 153. 153. 153. 153. 153. + 153. 154. 154. 155. 155. 155. 155. 154. 154. 151. 152. 154. 154. + 153. 151. 148. 147. 151. 150. 150. 149. 147. 144. 142. 140. 136. + 136. 138. 138. 138. 137. 136. 135. 95. 98. 98. 94. 93. 95. 94. 90. + 90. 88. 82. 76. 76. 89. 113. 131. 146. 155. 165. 173. 175. 175. 177. + 178. 179. 174. 175. 171. 157. 149. 136. 116. 89. 74. 72. 79. 81. 88. + 96. 94. 97. 98. 98. 98. 98. 98. 98. 97. 109. 85. 74. 85. 84. 155. + 196. 207. 161. 135. 135. 144. 145. 159. 146. 98. 144. 112. 82. 57. + 38. 41. 57. 61. 102. 55. 53. 84. 75. 46. 49. 70. 108. 92. 107. 98. + 46. 44. 42. 59. 34. 57. 41. 91. 86. 50. 47. 40. 39. 46. 57. 49. 46. + 77. 81. 38. 38. 38. 55. 145. 124. 119. 187. 174. 180. 178. 182. 193. + 201. 201. 196. 194. 156. 107. 68. 66. 66. 47. 41. 57. 77. 50. 60. + 64. 37. 51. 85. 82. 178. 202. 176. 136. 84. 56. 82. 85. 114. 117. + 123. 129. 134. 139. 143. 145. 154. 164. 185. 198. 208. 224. 199. + 138. 58. 56. 40. 45. 46. 74. 126. 121. 170. 126. 72. 43. 45. 55. 55. + 48. 48. 46. 51. 44. 51. 69. 57. 152. 174. 127. 85. 81. 63. 78. 60. + 59. 52. 47. 47. 50. 52. 50. 49. 50. 51. 63. 99. 140. 151. 138. 136. + 150. 160. 162. 160. 155. 155. 157. 156. 153. 153. 153. 153. 153. + 153. 153. 153. 153. 153. 153. 154. 154. 154. 154. 153. 153. 151. + 152. 153. 154. 153. 150. 147. 145. 150. 150. 149. 147. 145. 143. + 141. 140. 133. 133. 133. 133. 132. 132. 131. 131. 96. 99. 99. 95. + 94. 96. 94. 90. 89. 87. 81. 74. 74. 88. 112. 131. 146. 155. 165. + 173. 175. 175. 177. 178. 181. 176. 177. 172. 158. 149. 137. 116. 90. + 75. 74. 81. 83. 91. 99. 97. 100. 100. 100. 100. 100. 100. 100. 100. + 97. 94. 89. 92. 72. 122. 178. 156. 178. 147. 141. 152. 148. 145. + 143. 130. 150. 92. 58. 42. 33. 65. 100. 93. 56. 47. 61. 77. 61. 40. + 51. 73. 119. 92. 111. 89. 41. 46. 43. 49. 37. 40. 42. 76. 115. 56. + 46. 41. 46. 45. 48. 37. 30. 53. 62. 36. 51. 50. 107. 137. 104. 178. + 193. 151. 169. 179. 190. 198. 203. 202. 192. 181. 106. 97. 79. 68. + 60. 44. 45. 67. 98. 81. 73. 74. 71. 69. 70. 71. 192. 202. 202. 189. + 135. 81. 89. 116. 102. 107. 115. 122. 129. 134. 139. 143. 153. 170. + 188. 199. 214. 218. 168. 97. 68. 62. 68. 64. 57. 70. 93. 112. 171. + 142. 97. 59. 44. 45. 49. 49. 50. 47. 51. 45. 54. 71. 58. 150. 179. + 134. 83. 91. 69. 83. 63. 59. 51. 48. 48. 53. 54. 50. 48. 48. 50. 75. + 114. 142. 145. 135. 139. 152. 160. 161. 158. 154. 154. 157. 156. + 151. 152. 152. 152. 152. 152. 152. 152. 152. 152. 152. 153. 154. + 154. 153. 152. 152. 151. 151. 152. 152. 151. 149. 147. 146. 149. + 148. 147. 145. 143. 141. 139. 139. 133. 132. 130. 129. 129. 130. + 131. 132. 98. 101. 101. 97. 96. 97. 95. 91. 89. 86. 80. 73. 74. 88. + 113. 132. 146. 155. 165. 173. 175. 175. 177. 178. 182. 177. 178. + 173. 159. 150. 138. 117. 94. 79. 77. 84. 85. 93. 101. 98. 102. 102. + 102. 101. 101. 102. 102. 102. 90. 104. 95. 80. 53. 88. 164. 100. + 128. 170. 191. 172. 154. 146. 111. 63. 71. 44. 33. 45. 63. 84. 84. + 62. 39. 78. 67. 52. 67. 53. 50. 98. 120. 91. 121. 91. 41. 49. 46. + 46. 51. 42. 45. 58. 114. 64. 44. 50. 49. 39. 48. 59. 47. 33. 36. 43. + 43. 68. 114. 99. 117. 181. 162. 147. 164. 181. 193. 196. 198. 194. + 169. 139. 99. 112. 106. 93. 83. 61. 51. 67. 102. 121. 89. 69. 91. + 76. 70. 121. 214. 199. 207. 202. 162. 111. 89. 113. 103. 108. 113. + 119. 124. 131. 139. 145. 156. 176. 192. 207. 221. 200. 140. 90. 113. + 67. 95. 87. 82. 80. 62. 139. 165. 143. 104. 65. 44. 43. 47. 47. 48. + 44. 48. 45. 56. 73. 55. 143. 180. 138. 80. 96. 72. 85. 63. 58. 52. + 49. 50. 55. 56. 51. 47. 46. 53. 88. 128. 144. 139. 135. 144. 155. + 159. 159. 156. 153. 154. 157. 155. 150. 151. 151. 151. 151. 151. + 151. 151. 151. 151. 152. 153. 153. 153. 153. 152. 151. 151. 151. + 150. 150. 149. 148. 148. 148. 147. 146. 144. 141. 139. 138. 137. + 136. 132. 131. 130. 131. 135. 141. 147. 151. 99. 102. 102. 98. 97. + 98. 96. 92. 89. 86. 80. 73. 73. 88. 113. 132. 146. 155. 165. 173. + 175. 175. 177. 178. 183. 178. 179. 174. 160. 151. 138. 118. 97. 82. + 80. 86. 87. 93. 100. 98. 104. 104. 103. 103. 103. 103. 104. 104. + 115. 89. 56. 59. 43. 56. 163. 115. 159. 190. 215. 214. 178. 114. 59. + 41. 44. 45. 35. 46. 78. 84. 66. 57. 56. 68. 67. 67. 73. 70. 78. 105. + 117. 90. 130. 95. 44. 51. 50. 48. 62. 48. 42. 36. 92. 63. 38. 56. + 42. 48. 52. 47. 39. 38. 42. 44. 47. 109. 111. 97. 168. 161. 153. + 181. 180. 197. 205. 199. 194. 181. 138. 91. 123. 128. 123. 126. 123. + 85. 54. 62. 100. 106. 98. 77. 59. 67. 120. 184. 205. 197. 217. 196. + 161. 132. 102. 118. 112. 114. 117. 119. 123. 131. 141. 149. 158. + 179. 196. 217. 227. 187. 128. 103. 131. 119. 87. 84. 88. 82. 119. + 173. 172. 142. 96. 58. 45. 49. 49. 43. 45. 41. 46. 45. 58. 74. 52. + 137. 179. 138. 76. 97. 71. 84. 61. 54. 52. 50. 51. 56. 57. 51. 46. + 45. 56. 99. 138. 146. 137. 138. 149. 159. 158. 158. 155. 153. 154. + 157. 155. 149. 151. 151. 151. 151. 151. 151. 151. 151. 151. 152. + 152. 153. 153. 152. 152. 151. 151. 150. 149. 148. 148. 148. 149. + 149. 145. 143. 141. 139. 137. 135. 135. 134. 129. 129. 131. 136. + 145. 156. 167. 174. 102. 100. 98. 98. 98. 97. 95. 93. 91. 88. 81. + 73. 72. 87. 112. 132. 145. 157. 168. 172. 174. 178. 180. 178. 179. + 180. 177. 170. 162. 151. 133. 118. 101. 83. 81. 90. 92. 96. 104. + 105. 107. 107. 104. 112. 109. 104. 101. 77. 76. 51. 68. 63. 93. 119. + 150. 162. 171. 201. 233. 214. 151. 41. 67. 46. 41. 31. 49. 82. 93. + 87. 77. 67. 43. 66. 84. 94. 75. 102. 67. 121. 91. 87. 121. 107. 53. + 51. 54. 32. 55. 47. 44. 49. 53. 52. 53. 57. 49. 35. 49. 58. 38. 34. + 46. 39. 90. 143. 94. 154. 183. 155. 170. 183. 198. 193. 191. 200. + 182. 122. 99. 133. 118. 125. 135. 140. 134. 117. 94. 79. 104. 111. + 124. 125. 118. 138. 179. 205. 205. 201. 198. 181. 153. 139. 132. + 120. 135. 121. 114. 122. 129. 129. 133. 142. 158. 177. 200. 221. + 222. 179. 119. 86. 122. 128. 126. 105. 101. 138. 174. 178. 174. 135. + 92. 55. 52. 56. 45. 58. 47. 41. 52. 52. 69. 66. 57. 120. 171. 164. + 88. 80. 98. 71. 66. 54. 45. 53. 48. 44. 53. 53. 44. 41. 66. 112. + 140. 138. 136. 141. 150. 161. 156. 156. 155. 154. 154. 153. 152. + 152. 150. 149. 150. 154. 157. 158. 155. 151. 152. 152. 153. 153. + 153. 152. 151. 151. 148. 152. 151. 146. 145. 148. 145. 138. 137. + 141. 143. 141. 135. 130. 128. 128. 135. 143. 154. 161. 165. 169. + 176. 181. 103. 101. 100. 100. 100. 98. 95. 93. 90. 88. 82. 73. 73. + 87. 112. 132. 145. 156. 167. 172. 175. 178. 180. 179. 180. 181. 178. + 171. 163. 152. 134. 119. 101. 83. 81. 90. 92. 96. 104. 104. 110. + 109. 110. 110. 113. 101. 68. 43. 37. 58. 115. 131. 145. 163. 176. + 181. 180. 203. 169. 77. 49. 63. 104. 42. 58. 71. 101. 122. 114. 87. + 55. 29. 46. 86. 63. 81. 73. 89. 81. 113. 128. 53. 154. 116. 91. 45. + 75. 41. 46. 40. 39. 45. 50. 50. 51. 55. 45. 48. 58. 41. 33. 37. 36. + 58. 135. 113. 132. 187. 165. 160. 189. 180. 202. 196. 203. 173. 116. + 113. 134. 119. 125. 130. 138. 144. 143. 133. 119. 109. 105. 111. + 129. 139. 137. 147. 165. 171. 187. 185. 187. 180. 161. 148. 136. + 117. 131. 121. 117. 124. 128. 128. 132. 141. 158. 178. 200. 218. + 219. 185. 142. 124. 113. 127. 140. 138. 141. 164. 174. 159. 133. + 103. 77. 57. 64. 68. 51. 58. 51. 45. 55. 54. 71. 67. 57. 119. 170. + 166. 93. 81. 96. 71. 64. 52. 46. 49. 45. 46. 55. 53. 50. 56. 80. + 119. 140. 136. 137. 144. 153. 163. 156. 156. 155. 154. 153. 153. + 152. 152. 152. 152. 152. 155. 159. 159. 156. 153. 152. 152. 152. + 153. 152. 152. 151. 150. 147. 150. 148. 143. 142. 146. 145. 140. + 139. 140. 139. 136. 133. 133. 138. 143. 154. 161. 170. 176. 178. + 181. 187. 191. 103. 102. 101. 102. 102. 99. 95. 91. 88. 87. 82. 74. + 73. 86. 111. 131. 145. 156. 167. 172. 175. 178. 180. 179. 181. 182. + 180. 173. 165. 153. 136. 120. 101. 82. 81. 90. 92. 96. 103. 104. + 112. 110. 118. 108. 120. 108. 46. 30. 77. 104. 147. 153. 134. 147. + 147. 156. 178. 118. 70. 45. 41. 46. 84. 104. 102. 89. 84. 87. 76. + 53. 39. 38. 52. 104. 47. 83. 81. 62. 83. 112. 139. 82. 155. 100. 85. + 85. 76. 42. 43. 40. 40. 44. 48. 47. 47. 49. 46. 55. 55. 33. 35. 34. + 39. 101. 142. 92. 163. 196. 165. 171. 194. 192. 201. 210. 175. 114. + 95. 116. 131. 128. 133. 136. 140. 145. 147. 145. 139. 134. 120. 110. + 111. 114. 114. 125. 136. 134. 127. 132. 150. 165. 169. 172. 164. + 145. 127. 121. 122. 127. 128. 126. 131. 140. 153. 177. 202. 219. + 219. 192. 162. 154. 149. 149. 148. 137. 130. 137. 130. 104. 89. 74. + 67. 64. 78. 79. 54. 55. 51. 45. 56. 55. 71. 66. 54. 116. 169. 168. + 103. 83. 93. 69. 59. 50. 48. 45. 42. 51. 59. 52. 54. 74. 101. 128. + 139. 134. 139. 149. 156. 164. 156. 155. 155. 154. 153. 152. 152. + 152. 152. 152. 153. 155. 157. 157. 155. 153. 151. 152. 152. 152. + 151. 150. 149. 149. 146. 147. 145. 140. 139. 142. 143. 141. 138. + 137. 136. 133. 134. 142. 154. 164. 170. 175. 182. 185. 185. 186. + 190. 193. 103. 102. 102. 103. 102. 99. 93. 89. 85. 86. 82. 74. 71. + 84. 109. 130. 144. 156. 167. 172. 175. 179. 181. 179. 183. 184. 181. + 174. 166. 155. 137. 122. 100. 82. 80. 90. 91. 95. 103. 104. 110. + 109. 121. 103. 126. 128. 66. 73. 132. 138. 154. 160. 126. 135. 123. + 137. 111. 70. 56. 58. 48. 46. 67. 115. 111. 83. 73. 93. 95. 59. 32. + 38. 55. 100. 51. 96. 96. 50. 70. 111. 117. 127. 133. 90. 106. 111. + 50. 38. 48. 47. 47. 48. 48. 46. 45. 45. 52. 51. 37. 40. 38. 28. 72. + 139. 111. 115. 172. 170. 183. 176. 179. 205. 202. 177. 116. 88. 114. + 125. 122. 141. 139. 139. 141. 143. 145. 145. 142. 139. 154. 133. + 119. 112. 111. 123. 134. 132. 120. 125. 142. 156. 159. 161. 154. + 136. 124. 124. 127. 131. 128. 125. 129. 138. 147. 173. 201. 222. + 224. 197. 167. 158. 150. 141. 132. 119. 111. 118. 115. 95. 76. 71. + 78. 78. 87. 81. 53. 53. 46. 41. 53. 53. 69. 64. 51. 112. 168. 171. + 114. 85. 89. 68. 55. 49. 50. 43. 43. 57. 62. 47. 53. 85. 119. 135. + 136. 131. 141. 152. 157. 162. 155. 155. 154. 154. 153. 152. 151. + 151. 149. 150. 151. 152. 153. 153. 152. 151. 151. 151. 151. 151. + 150. 149. 148. 147. 144. 145. 145. 141. 139. 138. 137. 137. 131. + 134. 138. 141. 147. 158. 171. 181. 180. 183. 187. 187. 186. 186. + 187. 189. 102. 102. 101. 101. 100. 96. 91. 86. 83. 84. 81. 72. 68. + 81. 107. 129. 144. 155. 167. 172. 175. 179. 181. 180. 184. 185. 182. + 175. 167. 156. 138. 123. 100. 82. 80. 89. 91. 95. 103. 103. 110. + 109. 119. 98. 123. 142. 107. 135. 132. 126. 139. 149. 106. 90. 64. + 79. 84. 71. 61. 47. 39. 44. 48. 73. 137. 124. 108. 111. 113. 85. 61. + 66. 45. 81. 62. 87. 99. 78. 71. 94. 98. 119. 124. 117. 150. 80. 46. + 47. 47. 49. 50. 49. 47. 47. 46. 45. 49. 53. 28. 41. 31. 40. 122. + 139. 104. 157. 174. 155. 186. 178. 190. 203. 179. 106. 84. 110. 118. + 126. 140. 136. 144. 144. 144. 146. 147. 146. 143. 141. 154. 142. + 139. 138. 134. 137. 140. 133. 142. 144. 155. 158. 150. 149. 146. + 132. 125. 128. 133. 134. 129. 125. 128. 135. 147. 170. 195. 218. + 227. 203. 171. 160. 143. 139. 140. 136. 127. 128. 124. 108. 89. 90. + 99. 94. 93. 81. 54. 59. 44. 39. 53. 53. 70. 64. 50. 111. 166. 174. + 125. 86. 83. 66. 51. 50. 50. 44. 46. 61. 61. 41. 50. 89. 131. 139. + 133. 129. 143. 154. 156. 159. 155. 155. 154. 153. 152. 152. 151. + 151. 149. 150. 151. 151. 151. 151. 151. 151. 150. 150. 150. 150. + 149. 147. 146. 145. 143. 144. 145. 144. 139. 134. 131. 132. 128. + 137. 149. 159. 167. 175. 183. 189. 190. 191. 192. 191. 189. 188. + 188. 188. 101. 100. 99. 98. 96. 92. 87. 83. 82. 82. 78. 68. 63. 77. + 105. 129. 143. 155. 166. 172. 175. 179. 182. 181. 184. 185. 182. + 175. 167. 156. 138. 123. 99. 81. 79. 89. 91. 95. 102. 103. 110. 111. + 115. 97. 113. 137. 134. 165. 173. 153. 150. 132. 84. 65. 60. 85. 99. + 60. 32. 42. 65. 42. 40. 56. 85. 124. 139. 134. 132. 101. 56. 36. 33. + 65. 70. 64. 85. 112. 95. 81. 88. 110. 108. 136. 104. 68. 68. 59. 41. + 45. 47. 45. 44. 47. 49. 49. 42. 59. 35. 33. 31. 77. 149. 112. 126. + 171. 172. 170. 178. 189. 222. 181. 113. 90. 89. 112. 124. 128. 135. + 142. 149. 149. 151. 154. 156. 156. 154. 152. 145. 139. 144. 146. + 141. 144. 149. 143. 152. 153. 161. 163. 157. 160. 163. 153. 130. + 133. 137. 135. 130. 126. 128. 132. 152. 168. 187. 209. 224. 209. + 183. 173. 164. 156. 155. 149. 135. 128. 124. 113. 107. 107. 114. + 104. 98. 84. 59. 66. 45. 42. 56. 56. 72. 65. 50. 110. 165. 176. 135. + 86. 77. 65. 48. 53. 49. 45. 48. 60. 57. 37. 52. 96. 135. 138. 131. + 130. 147. 157. 154. 155. 154. 154. 154. 153. 152. 151. 151. 150. + 151. 152. 153. 153. 151. 151. 152. 153. 149. 149. 149. 149. 147. + 146. 144. 143. 143. 143. 144. 144. 138. 131. 130. 133. 137. 149. + 165. 178. 185. 188. 190. 191. 192. 192. 191. 190. 189. 188. 188. + 187. 100. 98. 95. 93. 92. 88. 84. 81. 80. 81. 76. 64. 59. 73. 103. + 129. 143. 154. 166. 171. 175. 180. 182. 181. 183. 184. 182. 175. + 167. 155. 138. 122. 99. 81. 79. 89. 90. 94. 102. 103. 111. 112. 111. + 103. 107. 123. 138. 152. 149. 124. 116. 78. 59. 67. 85. 101. 67. 61. + 38. 39. 84. 65. 82. 70. 92. 105. 90. 79. 89. 72. 45. 47. 37. 62. 77. + 62. 66. 100. 117. 107. 95. 105. 85. 113. 74. 85. 66. 55. 40. 46. 47. + 43. 42. 47. 51. 50. 47. 51. 44. 30. 61. 122. 134. 104. 153. 173. + 172. 191. 183. 201. 203. 126. 72. 106. 106. 106. 131. 130. 124. 149. + 153. 153. 154. 157. 161. 164. 164. 163. 166. 157. 157. 157. 152. + 160. 171. 171. 174. 169. 172. 170. 163. 162. 157. 142. 136. 139. + 139. 136. 131. 128. 128. 129. 151. 166. 184. 206. 223. 211. 190. + 184. 167. 154. 149. 145. 136. 135. 138. 133. 120. 115. 117. 108. + 105. 91. 61. 64. 48. 44. 58. 58. 72. 62. 45. 104. 164. 178. 141. 85. + 72. 64. 47. 56. 46. 46. 48. 55. 50. 38. 61. 110. 134. 137. 131. 134. + 152. 159. 154. 153. 154. 154. 153. 153. 152. 151. 150. 150. 150. + 152. 153. 152. 150. 149. 151. 153. 149. 149. 149. 148. 147. 145. + 143. 142. 143. 141. 141. 140. 135. 129. 133. 141. 157. 167. 182. + 191. 194. 193. 192. 191. 191. 190. 189. 188. 188. 188. 188. 187. + 100. 97. 93. 91. 88. 86. 82. 79. 80. 80. 74. 62. 56. 70. 102. 129. + 142. 154. 166. 171. 175. 180. 182. 181. 183. 184. 181. 174. 166. + 155. 137. 122. 99. 81. 79. 88. 90. 94. 102. 102. 109. 112. 109. 111. + 106. 113. 133. 129. 117. 102. 111. 78. 89. 101. 98. 71. 49. 52. 43. + 57. 98. 49. 101. 122. 115. 86. 56. 76. 104. 67. 27. 41. 50. 66. 82. + 81. 55. 60. 123. 149. 116. 78. 79. 82. 146. 87. 35. 41. 45. 51. 51. + 44. 41. 46. 50. 50. 58. 36. 45. 37. 99. 151. 105. 116. 172. 186. + 176. 200. 200. 202. 142. 63. 86. 93. 118. 127. 117. 128. 145. 138. + 155. 154. 154. 156. 160. 164. 165. 165. 173. 165. 166. 167. 163. + 167. 173. 168. 171. 164. 166. 169. 167. 167. 156. 135. 141. 142. + 140. 135. 131. 129. 128. 127. 144. 164. 186. 210. 224. 211. 189. + 183. 176. 161. 158. 159. 150. 143. 137. 126. 125. 116. 116. 108. + 109. 95. 60. 56. 49. 45. 58. 56. 69. 58. 39. 97. 164. 179. 145. 84. + 69. 64. 47. 58. 44. 46. 47. 50. 46. 41. 71. 122. 133. 136. 132. 137. + 156. 161. 154. 152. 154. 154. 153. 152. 152. 151. 150. 150. 148. + 150. 151. 149. 147. 146. 148. 151. 149. 149. 148. 147. 146. 144. + 143. 142. 144. 140. 137. 136. 132. 129. 137. 149. 173. 181. 191. + 197. 196. 193. 192. 191. 194. 192. 191. 191. 192. 192. 192. 192. 92. + 93. 94. 91. 86. 83. 83. 85. 82. 78. 72. 65. 62. 73. 101. 127. 140. + 152. 164. 169. 173. 178. 180. 179. 182. 183. 180. 173. 166. 156. + 140. 125. 99. 84. 76. 84. 95. 98. 99. 102. 107. 104. 103. 108. 117. + 121. 115. 106. 143. 135. 127. 138. 155. 139. 95. 62. 56. 60. 48. 78. + 104. 74. 121. 107. 111. 78. 73. 115. 92. 36. 40. 44. 45. 58. 106. + 125. 87. 69. 82. 82. 115. 98. 124. 144. 122. 73. 42. 62. 57. 44. 48. + 55. 44. 37. 46. 55. 50. 41. 44. 57. 143. 123. 97. 163. 169. 188. + 186. 194. 205. 166. 60. 77. 91. 105. 118. 121. 121. 127. 135. 141. + 145. 150. 156. 161. 164. 165. 166. 167. 173. 175. 173. 169. 168. + 172. 173. 170. 168. 170. 172. 172. 167. 159. 150. 144. 142. 139. + 135. 132. 130. 129. 128. 127. 141. 157. 184. 211. 221. 212. 192. + 178. 175. 169. 160. 151. 144. 140. 136. 133. 127. 127. 119. 115. + 112. 90. 65. 58. 47. 44. 59. 60. 65. 55. 43. 89. 159. 180. 160. 79. + 73. 46. 42. 63. 47. 44. 53. 56. 40. 47. 91. 131. 137. 130. 132. 146. + 159. 160. 156. 155. 153. 153. 152. 152. 152. 152. 151. 151. 151. + 152. 152. 151. 150. 149. 148. 147. 147. 146. 146. 145. 143. 142. + 142. 141. 138. 139. 137. 132. 130. 138. 155. 169. 189. 191. 195. + 198. 198. 196. 193. 191. 191. 190. 189. 188. 188. 189. 190. 191. 91. + 92. 92. 89. 85. 82. 82. 84. 77. 74. 69. 63. 60. 72. 101. 127. 141. + 153. 165. 170. 173. 178. 180. 179. 182. 183. 180. 173. 166. 155. + 139. 124. 100. 85. 77. 83. 91. 93. 95. 100. 104. 115. 127. 132. 134. + 139. 149. 156. 156. 170. 135. 99. 102. 90. 61. 55. 67. 62. 65. 82. + 93. 86. 125. 93. 89. 110. 110. 101. 61. 29. 40. 34. 56. 37. 50. 82. + 102. 117. 120. 103. 103. 130. 148. 104. 76. 100. 105. 96. 77. 51. + 43. 51. 49. 45. 45. 43. 51. 49. 40. 106. 136. 121. 114. 178. 179. + 186. 193. 197. 186. 68. 61. 73. 94. 107. 119. 122. 122. 127. 135. + 140. 145. 149. 155. 160. 162. 165. 167. 169. 174. 176. 175. 171. + 170. 174. 174. 172. 171. 172. 173. 171. 167. 159. 151. 146. 144. + 141. 137. 134. 131. 130. 128. 127. 137. 153. 181. 209. 221. 214. + 194. 179. 174. 168. 160. 152. 146. 141. 136. 133. 129. 130. 123. + 120. 116. 94. 68. 61. 49. 47. 60. 63. 68. 54. 41. 84. 157. 178. 159. + 94. 69. 46. 42. 58. 44. 44. 54. 53. 42. 57. 101. 134. 136. 132. 135. + 148. 159. 159. 156. 155. 153. 153. 152. 152. 152. 152. 151. 151. + 151. 151. 151. 151. 150. 149. 148. 147. 147. 147. 146. 145. 144. + 143. 142. 141. 138. 136. 133. 132. 137. 152. 170. 183. 190. 192. + 195. 197. 198. 196. 193. 191. 190. 190. 189. 189. 190. 191. 193. + 194. 89. 90. 89. 87. 83. 81. 81. 81. 73. 70. 66. 60. 59. 72. 101. + 128. 142. 154. 165. 171. 174. 178. 181. 180. 183. 183. 180. 173. + 165. 155. 138. 123. 99. 86. 78. 83. 89. 92. 98. 106. 122. 132. 143. + 145. 140. 138. 144. 151. 122. 89. 62. 66. 74. 62. 57. 71. 71. 50. + 75. 91. 86. 85. 114. 105. 114. 133. 102. 59. 42. 45. 52. 36. 39. 45. + 58. 68. 73. 83. 103. 119. 118. 75. 52. 40. 76. 141. 134. 88. 77. 49. + 38. 47. 49. 47. 47. 44. 43. 45. 56. 140. 127. 107. 144. 184. 184. + 200. 198. 197. 110. 29. 52. 88. 98. 111. 122. 123. 123. 128. 135. + 138. 145. 149. 153. 157. 161. 164. 169. 172. 175. 178. 177. 174. + 174. 176. 176. 173. 174. 174. 173. 171. 166. 159. 153. 149. 147. + 144. 140. 136. 132. 130. 129. 129. 133. 150. 178. 206. 222. 217. + 197. 180. 171. 167. 160. 154. 148. 142. 136. 132. 129. 131. 126. + 123. 119. 95. 68. 61. 50. 51. 61. 66. 72. 53. 40. 76. 156. 174. 155. + 116. 61. 46. 41. 52. 43. 47. 53. 47. 43. 70. 114. 137. 136. 135. + 140. 151. 158. 159. 156. 154. 153. 153. 153. 152. 152. 151. 151. + 151. 150. 151. 151. 150. 150. 148. 147. 146. 147. 147. 146. 146. + 144. 143. 141. 140. 139. 134. 130. 135. 149. 168. 184. 193. 192. + 193. 195. 197. 197. 195. 193. 191. 189. 189. 190. 191. 193. 195. + 197. 198. 86. 86. 85. 84. 81. 79. 79. 78. 73. 70. 65. 60. 58. 71. + 100. 127. 143. 155. 166. 171. 174. 178. 180. 179. 183. 183. 180. + 173. 165. 154. 137. 122. 96. 85. 80. 85. 91. 95. 105. 117. 131. 128. + 128. 134. 136. 128. 115. 106. 104. 49. 54. 88. 77. 63. 66. 59. 61. + 66. 93. 79. 79. 105. 116. 124. 121. 113. 68. 38. 49. 58. 52. 48. 51. + 52. 47. 50. 67. 74. 71. 72. 102. 35. 22. 48. 90. 133. 131. 111. 73. + 51. 46. 51. 45. 40. 47. 51. 35. 41. 104. 138. 122. 109. 179. 181. + 182. 207. 202. 133. 38. 53. 54. 100. 103. 114. 124. 125. 125. 129. + 134. 136. 145. 148. 151. 155. 158. 163. 169. 174. 175. 178. 179. + 177. 177. 179. 178. 174. 176. 175. 173. 169. 164. 158. 153. 150. + 148. 147. 143. 138. 133. 130. 129. 130. 134. 150. 177. 204. 222. + 220. 200. 180. 168. 165. 160. 156. 151. 144. 138. 133. 126. 130. + 126. 123. 117. 92. 65. 58. 49. 53. 58. 69. 76. 53. 40. 70. 155. 170. + 148. 135. 54. 43. 41. 48. 47. 51. 51. 39. 42. 83. 126. 139. 135. + 139. 147. 155. 158. 158. 155. 154. 154. 154. 153. 152. 152. 151. + 150. 150. 150. 150. 150. 150. 149. 148. 146. 146. 146. 146. 146. + 146. 144. 142. 140. 139. 138. 133. 132. 143. 162. 180. 191. 194. + 193. 194. 195. 196. 195. 194. 193. 192. 190. 190. 192. 194. 196. + 199. 201. 202. 84. 83. 81. 80. 79. 78. 76. 75. 75. 72. 66. 60. 58. + 70. 98. 125. 143. 155. 166. 171. 174. 178. 179. 178. 182. 182. 179. + 172. 165. 154. 137. 122. 95. 84. 79. 85. 91. 96. 106. 117. 112. 107. + 110. 123. 129. 118. 99. 86. 79. 93. 100. 90. 76. 67. 58. 47. 69. + 104. 104. 53. 79. 143. 125. 120. 70. 78. 69. 52. 52. 45. 37. 54. 53. + 48. 36. 41. 70. 83. 67. 51. 78. 48. 48. 55. 81. 124. 132. 122. 86. + 59. 47. 50. 43. 38. 42. 43. 34. 61. 145. 129. 111. 148. 198. 182. + 189. 197. 172. 43. 32. 55. 75. 91. 106. 116. 124. 125. 126. 130. + 134. 135. 144. 146. 149. 152. 156. 161. 168. 173. 173. 178. 180. + 178. 178. 180. 178. 174. 176. 175. 172. 168. 162. 156. 151. 149. + 147. 147. 144. 139. 133. 129. 129. 131. 137. 152. 175. 201. 221. + 223. 203. 180. 166. 164. 160. 156. 152. 146. 139. 134. 127. 131. + 127. 123. 115. 89. 62. 55. 47. 53. 53. 70. 79. 52. 42. 64. 154. 167. + 142. 146. 55. 40. 40. 45. 55. 55. 49. 35. 45. 93. 134. 138. 135. + 144. 154. 159. 158. 156. 155. 154. 154. 154. 153. 152. 152. 151. + 150. 150. 149. 149. 149. 149. 148. 147. 145. 145. 145. 146. 146. + 145. 144. 141. 138. 136. 130. 131. 138. 155. 175. 189. 193. 192. + 194. 194. 194. 194. 194. 194. 194. 194. 192. 193. 195. 198. 200. + 202. 204. 204. 81. 79. 77. 77. 77. 76. 74. 72. 75. 71. 66. 60. 57. + 69. 97. 124. 143. 154. 165. 170. 172. 176. 178. 177. 180. 181. 178. + 172. 165. 154. 138. 124. 97. 84. 78. 83. 90. 93. 99. 108. 104. 106. + 114. 121. 113. 95. 85. 85. 81. 116. 86. 68. 102. 78. 47. 84. 103. + 98. 70. 53. 91. 138. 107. 110. 58. 70. 75. 51. 42. 48. 44. 55. 43. + 55. 60. 51. 44. 53. 60. 58. 81. 48. 30. 37. 86. 133. 131. 127. 103. + 59. 31. 34. 40. 43. 41. 33. 41. 96. 144. 123. 107. 189. 193. 186. + 199. 185. 90. 32. 45. 51. 81. 85. 108. 117. 124. 125. 126. 130. 133. + 133. 142. 145. 148. 151. 154. 159. 165. 169. 171. 176. 179. 178. + 179. 180. 177. 172. 174. 173. 170. 166. 160. 154. 148. 145. 144. + 145. 143. 138. 131. 127. 128. 131. 138. 152. 172. 195. 217. 224. + 205. 180. 165. 163. 159. 156. 152. 147. 141. 137. 131. 134. 130. + 123. 113. 86. 60. 54. 46. 55. 49. 70. 81. 50. 42. 58. 152. 166. 139. + 153. 68. 40. 40. 43. 60. 56. 48. 39. 55. 104. 139. 137. 134. 148. + 161. 162. 158. 155. 154. 153. 155. 154. 154. 153. 151. 150. 150. + 149. 148. 148. 148. 148. 147. 146. 145. 144. 143. 144. 145. 144. + 142. 139. 135. 133. 123. 132. 148. 168. 186. 195. 196. 194. 194. + 193. 193. 193. 193. 194. 195. 196. 196. 197. 199. 201. 203. 204. + 205. 205. 79. 77. 74. 74. 75. 75. 73. 70. 71. 68. 63. 58. 56. 68. + 97. 124. 142. 153. 164. 169. 171. 175. 176. 175. 178. 179. 177. 171. + 165. 155. 139. 125. 98. 83. 75. 82. 91. 94. 97. 103. 111. 112. 117. + 118. 104. 90. 93. 107. 128. 108. 75. 90. 121. 86. 64. 111. 102. 65. + 45. 65. 75. 110. 103. 101. 92. 70. 66. 44. 40. 60. 55. 55. 59. 52. + 53. 46. 39. 57. 62. 38. 67. 49. 41. 56. 100. 116. 114. 153. 135. 81. + 40. 32. 36. 40. 41. 34. 62. 126. 125. 115. 139. 197. 189. 196. 193. + 131. 31. 58. 48. 57. 71. 91. 108. 116. 123. 124. 126. 131. 133. 133. + 141. 143. 147. 150. 153. 156. 161. 165. 168. 174. 178. 178. 178. + 179. 176. 170. 171. 170. 168. 164. 158. 151. 145. 141. 140. 142. + 141. 136. 129. 126. 128. 131. 136. 148. 165. 187. 213. 224. 208. + 182. 165. 162. 159. 155. 152. 148. 143. 139. 132. 135. 129. 120. + 108. 80. 55. 51. 48. 58. 46. 69. 80. 46. 40. 52. 148. 166. 141. 158. + 90. 43. 41. 41. 61. 54. 49. 49. 71. 116. 143. 137. 134. 151. 166. + 165. 158. 155. 154. 153. 155. 155. 154. 153. 151. 150. 149. 149. + 148. 148. 148. 147. 147. 145. 144. 143. 141. 142. 143. 143. 141. + 137. 133. 131. 127. 142. 163. 182. 192. 196. 197. 197. 193. 192. + 192. 192. 193. 195. 197. 199. 200. 201. 203. 204. 205. 205. 204. + 204. 78. 76. 73. 73. 75. 75. 72. 69. 67. 64. 60. 55. 55. 68. 98. + 125. 141. 152. 163. 168. 170. 174. 175. 174. 177. 178. 176. 171. + 165. 156. 140. 126. 96. 81. 74. 83. 95. 99. 101. 105. 107. 102. 104. + 111. 113. 115. 131. 151. 108. 68. 87. 111. 84. 79. 104. 105. 60. 60. + 65. 63. 33. 109. 139. 88. 102. 58. 63. 60. 50. 56. 47. 51. 44. 38. + 50. 51. 43. 68. 80. 49. 47. 52. 45. 50. 99. 110. 86. 112. 178. 124. + 76. 51. 34. 30. 37. 40. 87. 144. 118. 107. 187. 187. 198. 208. 177. + 50. 36. 45. 57. 51. 68. 93. 108. 116. 122. 124. 126. 131. 133. 132. + 140. 143. 147. 150. 152. 155. 159. 162. 166. 172. 176. 177. 177. + 178. 174. 169. 168. 168. 166. 163. 157. 150. 143. 138. 138. 140. + 140. 135. 128. 124. 127. 131. 132. 144. 160. 182. 210. 224. 209. + 184. 166. 162. 158. 154. 151. 148. 144. 141. 130. 133. 126. 116. + 103. 75. 50. 46. 51. 61. 45. 69. 79. 42. 38. 47. 145. 167. 144. 162. + 106. 47. 41. 39. 59. 51. 50. 58. 84. 125. 146. 136. 133. 153. 169. + 167. 158. 154. 154. 153. 156. 155. 154. 153. 151. 150. 149. 148. + 147. 147. 147. 147. 146. 145. 144. 143. 140. 141. 142. 142. 140. + 136. 132. 129. 137. 154. 176. 191. 195. 194. 195. 197. 192. 192. + 191. 191. 192. 195. 198. 200. 203. 204. 205. 206. 206. 205. 204. + 203. 77. 76. 74. 74. 76. 76. 75. 73. 70. 67. 63. 56. 53. 67. 99. + 128. 143. 152. 161. 167. 171. 175. 174. 169. 176. 177. 174. 168. + 162. 153. 138. 124. 107. 73. 77. 69. 99. 135. 101. 93. 107. 109. + 114. 134. 155. 138. 93. 65. 47. 103. 119. 119. 71. 124. 100. 46. 41. + 105. 58. 83. 51. 122. 139. 105. 131. 63. 53. 40. 72. 58. 65. 41. 59. + 32. 47. 51. 39. 56. 68. 61. 53. 47. 62. 60. 104. 130. 127. 68. 111. + 156. 148. 42. 42. 43. 19. 58. 138. 117. 114. 134. 202. 197. 197. + 216. 76. 45. 37. 50. 64. 47. 81. 91. 102. 109. 119. 125. 127. 129. + 131. 134. 137. 141. 146. 150. 152. 155. 159. 161. 161. 167. 173. + 176. 174. 171. 170. 171. 172. 167. 163. 163. 160. 151. 140. 134. + 136. 134. 133. 131. 127. 123. 124. 127. 134. 138. 157. 183. 205. + 223. 214. 185. 161. 160. 157. 151. 147. 145. 141. 137. 136. 129. + 126. 120. 96. 63. 46. 47. 55. 60. 51. 74. 82. 44. 33. 48. 133. 167. + 135. 141. 130. 54. 34. 45. 55. 55. 39. 52. 106. 138. 137. 136. 144. + 152. 161. 164. 161. 156. 155. 155. 153. 153. 152. 151. 150. 150. + 149. 148. 147. 147. 146. 145. 145. 144. 143. 143. 141. 144. 142. + 137. 136. 136. 133. 126. 146. 169. 188. 192. 192. 197. 196. 189. + 193. 193. 193. 194. 196. 199. 202. 204. 208. 208. 208. 207. 205. + 203. 201. 200. 79. 77. 75. 75. 75. 74. 72. 70. 69. 66. 61. 55. 52. + 65. 97. 127. 142. 152. 161. 167. 171. 175. 174. 170. 176. 177. 175. + 168. 162. 153. 138. 124. 95. 68. 80. 79. 107. 135. 96. 83. 121. 138. + 153. 155. 131. 82. 50. 53. 88. 122. 140. 106. 99. 81. 70. 43. 68. + 98. 86. 79. 80. 131. 128. 115. 105. 96. 53. 58. 63. 46. 63. 45. 41. + 39. 37. 48. 44. 62. 96. 71. 87. 52. 68. 79. 115. 156. 163. 88. 57. + 129. 157. 58. 33. 33. 36. 87. 120. 132. 113. 163. 202. 212. 205. + 141. 53. 33. 36. 57. 73. 49. 74. 80. 102. 109. 119. 125. 127. 128. + 131. 134. 137. 141. 145. 149. 152. 154. 158. 160. 161. 165. 169. + 171. 172. 171. 170. 170. 170. 167. 164. 162. 157. 150. 141. 135. + 135. 134. 133. 131. 127. 123. 123. 125. 133. 138. 157. 181. 203. + 223. 219. 195. 161. 159. 155. 151. 147. 144. 140. 137. 133. 129. + 126. 117. 91. 59. 44. 46. 56. 63. 54. 76. 83. 46. 34. 47. 120. 164. + 143. 147. 131. 55. 34. 47. 53. 50. 42. 64. 115. 141. 136. 135. 147. + 154. 161. 163. 159. 155. 154. 155. 154. 153. 153. 152. 151. 150. + 149. 149. 147. 147. 146. 146. 145. 144. 143. 143. 142. 142. 141. + 139. 136. 133. 132. 133. 155. 175. 191. 193. 193. 197. 196. 191. + 192. 193. 194. 196. 199. 201. 203. 204. 208. 208. 207. 207. 205. + 203. 202. 201. 81. 79. 76. 75. 74. 73. 70. 68. 67. 64. 59. 52. 49. + 63. 96. 125. 141. 151. 162. 167. 171. 175. 174. 171. 176. 177. 175. + 169. 163. 153. 138. 124. 96. 71. 76. 74. 101. 133. 117. 117. 144. + 135. 131. 135. 115. 68. 51. 72. 114. 129. 103. 102. 92. 75. 42. 63. + 91. 95. 115. 71. 108. 133. 114. 129. 85. 131. 52. 68. 60. 47. 62. + 46. 27. 47. 31. 49. 53. 73. 122. 83. 71. 45. 82. 108. 129. 179. 193. + 110. 40. 88. 125. 57. 30. 26. 50. 107. 134. 128. 125. 189. 206. 220. + 153. 43. 37. 26. 36. 61. 81. 53. 71. 79. 102. 109. 118. 125. 127. + 128. 131. 133. 136. 140. 144. 148. 150. 153. 156. 159. 161. 161. + 162. 165. 168. 170. 170. 168. 168. 167. 164. 160. 154. 147. 141. + 136. 132. 133. 133. 130. 126. 123. 122. 122. 130. 135. 154. 176. + 196. 220. 224. 207. 161. 158. 153. 150. 147. 143. 139. 136. 130. + 129. 125. 112. 83. 54. 42. 46. 55. 65. 58. 78. 84. 47. 34. 45. 104. + 160. 154. 153. 133. 60. 35. 48. 49. 44. 46. 80. 127. 143. 136. 136. + 152. 156. 160. 160. 157. 153. 153. 154. 154. 154. 153. 152. 152. + 151. 150. 150. 147. 147. 147. 146. 145. 144. 144. 143. 143. 139. + 139. 141. 135. 129. 133. 144. 168. 183. 195. 195. 193. 196. 196. + 192. 192. 194. 197. 200. 203. 204. 205. 205. 207. 207. 207. 207. + 206. 204. 203. 202. 81. 78. 76. 75. 74. 73. 70. 68. 66. 62. 56. 49. + 46. 61. 94. 124. 140. 151. 162. 167. 171. 174. 174. 172. 176. 177. + 176. 170. 164. 154. 138. 123. 99. 77. 75. 68. 87. 120. 126. 140. + 144. 112. 98. 118. 121. 84. 67. 90. 122. 108. 67. 90. 82. 85. 58. + 84. 88. 104. 119. 66. 113. 119. 110. 143. 77. 130. 54. 48. 56. 55. + 55. 39. 33. 47. 36. 52. 61. 80. 115. 88. 56. 73. 113. 115. 116. 164. + 184. 127. 51. 53. 78. 44. 29. 25. 70. 135. 127. 97. 160. 203. 206. + 194. 81. 38. 37. 31. 37. 60. 84. 56. 74. 88. 101. 109. 118. 124. + 126. 128. 130. 133. 135. 139. 143. 146. 149. 151. 154. 157. 159. + 157. 156. 159. 164. 168. 168. 166. 165. 166. 164. 157. 150. 145. + 140. 134. 127. 131. 132. 129. 125. 123. 121. 118. 129. 134. 151. + 169. 188. 214. 225. 214. 163. 157. 152. 151. 149. 144. 139. 137. + 129. 130. 124. 104. 74. 49. 43. 47. 52. 67. 61. 77. 82. 47. 34. 41. + 94. 157. 160. 154. 135. 70. 38. 45. 46. 39. 52. 96. 135. 142. 137. + 139. 156. 158. 159. 157. 154. 152. 152. 153. 154. 153. 153. 153. + 152. 152. 151. 151. 148. 148. 147. 146. 145. 145. 144. 144. 143. + 137. 138. 141. 135. 127. 138. 158. 180. 190. 196. 195. 192. 194. + 195. 193. 193. 196. 200. 204. 207. 207. 206. 206. 207. 207. 207. + 207. 206. 205. 204. 203. 80. 78. 76. 75. 75. 75. 73. 71. 65. 61. 55. + 47. 44. 59. 92. 123. 138. 151. 163. 168. 170. 173. 175. 174. 176. + 178. 176. 171. 165. 155. 138. 123. 92. 80. 78. 73. 80. 98. 106. 120. + 120. 110. 118. 140. 128. 75. 56. 83. 115. 82. 95. 81. 93. 72. 93. + 80. 74. 120. 98. 69. 102. 99. 116. 153. 75. 98. 74. 23. 46. 50. 45. + 42. 49. 41. 45. 52. 63. 79. 86. 84. 77. 124. 125. 81. 68. 108. 119. + 97. 42. 41. 59. 34. 30. 42. 99. 149. 118. 123. 204. 205. 186. 111. + 25. 51. 40. 37. 40. 62. 91. 60. 73. 89. 101. 108. 118. 124. 126. + 127. 130. 133. 134. 137. 142. 145. 147. 149. 152. 155. 157. 154. + 153. 155. 161. 165. 165. 164. 162. 165. 162. 153. 147. 144. 136. + 128. 122. 129. 133. 129. 126. 125. 122. 116. 131. 136. 151. 167. + 185. 212. 226. 218. 166. 157. 151. 152. 151. 144. 138. 137. 129. + 130. 120. 94. 64. 47. 45. 49. 48. 68. 63. 75. 78. 47. 34. 39. 88. + 153. 162. 150. 138. 85. 43. 41. 43. 38. 62. 109. 137. 140. 140. 144. + 159. 159. 158. 155. 153. 151. 151. 152. 153. 153. 152. 152. 152. + 152. 151. 151. 148. 148. 147. 147. 146. 145. 144. 144. 143. 137. + 136. 140. 134. 130. 146. 171. 188. 193. 196. 194. 191. 192. 193. + 193. 195. 198. 203. 207. 209. 208. 207. 205. 206. 206. 207. 207. + 207. 206. 205. 205. 81. 79. 77. 76. 77. 77. 75. 73. 64. 60. 53. 45. + 43. 58. 92. 122. 137. 151. 164. 168. 170. 173. 175. 175. 175. 178. + 177. 172. 166. 155. 138. 123. 93. 81. 72. 73. 82. 94. 107. 117. 109. + 112. 123. 135. 116. 71. 60. 89. 80. 81. 115. 100. 78. 70. 93. 72. + 79. 124. 70. 75. 100. 83. 120. 156. 85. 70. 107. 29. 43. 46. 48. 58. + 56. 41. 45. 47. 61. 77. 72. 83. 98. 150. 134. 87. 69. 88. 72. 58. + 38. 42. 45. 26. 57. 90. 118. 110. 117. 161. 185. 178. 158. 54. 23. + 27. 37. 39. 42. 66. 102. 66. 68. 81. 100. 108. 117. 123. 126. 127. + 130. 132. 133. 136. 141. 144. 145. 147. 150. 153. 154. 153. 153. + 155. 158. 161. 162. 162. 160. 163. 158. 150. 146. 143. 132. 118. + 119. 129. 135. 132. 130. 131. 126. 119. 133. 137. 151. 167. 185. + 213. 228. 219. 166. 155. 148. 151. 151. 143. 137. 136. 129. 129. + 113. 80. 53. 45. 48. 51. 45. 69. 64. 72. 75. 47. 36. 40. 77. 145. + 163. 148. 142. 101. 49. 40. 38. 41. 77. 122. 138. 139. 144. 147. + 160. 158. 157. 154. 153. 152. 151. 151. 151. 151. 151. 151. 151. + 151. 151. 151. 149. 148. 148. 147. 146. 145. 145. 145. 142. 138. + 135. 135. 133. 138. 158. 181. 193. 195. 195. 194. 192. 191. 192. + 193. 198. 201. 204. 207. 209. 208. 206. 205. 205. 206. 207. 207. + 208. 207. 207. 206. 84. 82. 80. 78. 78. 77. 74. 72. 64. 60. 53. 45. + 42. 57. 92. 123. 136. 150. 164. 169. 169. 172. 175. 176. 175. 178. + 177. 173. 167. 156. 138. 123. 97. 82. 69. 82. 103. 115. 122. 120. + 107. 111. 110. 107. 96. 75. 75. 99. 65. 99. 110. 102. 67. 78. 73. + 66. 106. 108. 46. 75. 113. 77. 114. 149. 106. 56. 116. 52. 48. 51. + 62. 61. 51. 53. 38. 41. 62. 80. 94. 94. 89. 128. 135. 127. 92. 88. + 62. 49. 43. 39. 35. 47. 115. 140. 135. 101. 110. 145. 145. 160. 129. + 55. 49. 34. 39. 42. 41. 67. 109. 72. 68. 80. 100. 108. 117. 123. + 125. 127. 129. 132. 132. 135. 140. 142. 144. 146. 149. 151. 152. + 153. 156. 156. 157. 157. 159. 161. 160. 161. 155. 147. 145. 143. + 128. 108. 119. 132. 139. 136. 135. 138. 133. 124. 129. 131. 145. + 163. 184. 213. 227. 216. 165. 151. 144. 149. 150. 141. 134. 134. + 128. 125. 103. 67. 43. 42. 49. 50. 44. 70. 65. 70. 73. 49. 40. 43. + 59. 136. 167. 150. 147. 113. 55. 42. 33. 46. 93. 136. 141. 141. 149. + 149. 159. 157. 156. 154. 153. 152. 151. 150. 149. 150. 150. 150. + 150. 150. 150. 150. 149. 149. 148. 147. 146. 146. 145. 145. 141. + 139. 135. 131. 133. 147. 170. 188. 196. 195. 195. 195. 194. 193. + 194. 195. 202. 203. 205. 207. 208. 207. 205. 204. 205. 205. 206. + 207. 208. 208. 208. 207. 88. 85. 82. 80. 79. 76. 73. 71. 65. 60. 53. + 45. 42. 57. 92. 123. 136. 150. 164. 169. 169. 172. 175. 176. 175. + 178. 178. 173. 167. 156. 138. 123. 92. 81. 76. 106. 134. 133. 118. + 94. 98. 118. 123. 108. 85. 64. 66. 88. 91. 114. 121. 66. 94. 68. 70. + 56. 132. 87. 34. 71. 127. 75. 103. 140. 120. 46. 99. 64. 52. 58. 69. + 45. 44. 68. 31. 38. 65. 85. 124. 107. 51. 67. 96. 116. 57. 42. 33. + 32. 36. 30. 42. 91. 165. 161. 157. 155. 138. 144. 172. 184. 96. 44. + 28. 45. 46. 46. 40. 64. 110. 76. 72. 87. 100. 107. 117. 123. 125. + 127. 129. 132. 132. 135. 139. 142. 143. 145. 148. 150. 150. 154. + 158. 158. 156. 155. 157. 160. 159. 159. 153. 145. 145. 144. 125. + 102. 120. 134. 142. 140. 140. 143. 138. 128. 123. 124. 139. 158. + 181. 212. 224. 212. 163. 149. 141. 147. 148. 139. 131. 132. 127. + 122. 97. 59. 37. 40. 49. 49. 44. 72. 67. 70. 73. 50. 43. 45. 45. + 130. 170. 154. 151. 120. 59. 45. 29. 50. 105. 145. 144. 144. 153. + 149. 158. 157. 155. 154. 154. 153. 151. 150. 148. 148. 149. 149. + 149. 149. 149. 149. 149. 149. 148. 147. 147. 146. 145. 145. 140. + 140. 135. 128. 132. 153. 177. 191. 197. 196. 196. 197. 196. 195. + 195. 197. 204. 205. 206. 207. 206. 205. 204. 203. 204. 205. 206. + 207. 208. 208. 208. 208. 86. 81. 76. 76. 79. 79. 75. 70. 62. 66. 61. + 46. 43. 66. 101. 125. 142. 150. 161. 168. 170. 170. 171. 173. 176. + 180. 180. 174. 166. 155. 139. 125. 107. 104. 105. 109. 104. 95. 96. + 104. 100. 115. 116. 108. 93. 63. 62. 98. 110. 100. 98. 85. 66. 50. + 59. 104. 120. 75. 54. 42. 119. 82. 86. 142. 143. 53. 94. 124. 44. + 51. 49. 44. 58. 71. 46. 42. 44. 71. 52. 41. 40. 46. 89. 101. 86. 38. + 34. 35. 51. 33. 11. 155. 164. 174. 169. 174. 176. 190. 172. 111. 56. + 37. 37. 35. 44. 41. 40. 67. 96. 83. 68. 85. 101. 109. 119. 126. 128. + 128. 129. 130. 132. 135. 139. 141. 143. 144. 147. 149. 152. 152. + 151. 152. 153. 156. 158. 159. 159. 158. 155. 150. 146. 139. 125. + 111. 125. 138. 139. 124. 118. 128. 136. 133. 115. 125. 133. 145. + 174. 204. 209. 196. 150. 147. 150. 148. 142. 145. 140. 122. 129. + 113. 68. 39. 44. 46. 45. 57. 54. 58. 77. 60. 71. 48. 41. 44. 46. + 116. 169. 159. 138. 134. 61. 43. 38. 45. 115. 149. 143. 145. 144. + 160. 159. 158. 156. 154. 152. 151. 151. 150. 150. 151. 151. 151. + 151. 150. 149. 148. 148. 148. 147. 146. 144. 143. 142. 142. 136. + 138. 133. 127. 138. 165. 185. 190. 199. 197. 194. 192. 192. 195. + 198. 201. 204. 203. 203. 204. 204. 206. 207. 208. 206. 207. 209. + 210. 210. 209. 207. 207. 86. 83. 80. 79. 81. 80. 77. 74. 63. 67. 63. + 51. 49. 71. 104. 127. 144. 152. 162. 169. 171. 171. 172. 174. 176. + 180. 180. 174. 166. 155. 139. 126. 105. 90. 80. 82. 85. 87. 93. 101. + 100. 117. 113. 99. 90. 74. 73. 93. 91. 126. 106. 88. 66. 37. 80. + 148. 86. 71. 67. 48. 109. 97. 85. 130. 172. 82. 67. 133. 49. 48. 51. + 74. 60. 62. 44. 29. 46. 49. 56. 73. 58. 120. 136. 56. 24. 36. 62. + 45. 29. 26. 64. 174. 162. 189. 187. 183. 190. 156. 104. 57. 32. 28. + 36. 43. 47. 43. 41. 68. 98. 86. 73. 90. 100. 108. 117. 123. 124. + 125. 127. 129. 132. 135. 139. 142. 144. 145. 148. 150. 151. 151. + 151. 152. 153. 155. 158. 159. 158. 158. 155. 150. 147. 141. 128. + 116. 135. 130. 106. 72. 61. 77. 95. 101. 121. 125. 126. 135. 162. + 191. 193. 178. 155. 148. 149. 147. 140. 140. 137. 124. 125. 96. 56. + 39. 44. 47. 46. 51. 56. 61. 74. 59. 69. 49. 45. 48. 39. 103. 164. + 160. 133. 136. 69. 41. 49. 63. 126. 150. 141. 145. 146. 159. 159. + 158. 156. 154. 152. 151. 151. 150. 150. 150. 151. 151. 150. 150. + 149. 148. 148. 148. 147. 145. 144. 143. 142. 142. 138. 139. 133. + 130. 144. 171. 189. 192. 199. 197. 195. 194. 194. 197. 201. 203. + 204. 204. 204. 204. 205. 206. 208. 209. 207. 208. 209. 210. 209. + 208. 207. 206. 84. 83. 82. 80. 79. 78. 76. 76. 64. 68. 66. 58. 59. + 79. 109. 130. 146. 154. 164. 170. 171. 172. 173. 175. 176. 180. 180. + 175. 167. 156. 140. 126. 105. 83. 66. 70. 83. 91. 97. 102. 104. 119. + 112. 93. 86. 84. 84. 91. 92. 141. 109. 79. 42. 32. 104. 128. 66. 77. + 85. 58. 94. 115. 86. 123. 160. 113. 53. 143. 62. 44. 43. 69. 57. 72. + 62. 21. 42. 31. 47. 68. 72. 129. 133. 59. 43. 44. 48. 29. 30. 40. + 96. 164. 172. 195. 180. 188. 191. 120. 49. 26. 33. 37. 39. 43. 49. + 44. 43. 71. 102. 92. 78. 95. 103. 109. 117. 121. 123. 124. 127. 130. + 132. 135. 139. 142. 144. 146. 149. 152. 150. 150. 150. 151. 153. + 155. 157. 158. 157. 158. 156. 152. 149. 145. 134. 123. 135. 133. + 116. 93. 86. 98. 106. 105. 107. 109. 111. 122. 152. 180. 182. 167. + 160. 148. 147. 147. 138. 135. 135. 128. 116. 74. 45. 43. 46. 49. 51. + 48. 58. 67. 72. 60. 66. 49. 49. 51. 34. 87. 160. 165. 130. 140. 82. + 40. 61. 87. 139. 151. 140. 146. 150. 157. 158. 157. 155. 154. 152. + 151. 151. 150. 150. 150. 151. 151. 150. 149. 148. 148. 148. 147. + 146. 145. 144. 143. 142. 141. 140. 138. 132. 134. 152. 179. 193. + 194. 198. 197. 196. 196. 198. 201. 204. 206. 206. 205. 205. 206. + 206. 208. 209. 210. 209. 209. 210. 210. 209. 208. 207. 206. 79. 80. + 80. 79. 76. 74. 74. 75. 65. 68. 68. 66. 70. 88. 114. 134. 148. 155. + 164. 169. 170. 171. 172. 174. 176. 180. 180. 175. 167. 157. 141. + 127. 102. 82. 70. 79. 93. 99. 100. 101. 110. 117. 113. 96. 82. 77. + 82. 92. 75. 94. 75. 53. 37. 83. 141. 92. 71. 85. 90. 63. 78. 119. + 83. 121. 128. 142. 70. 138. 73. 35. 39. 49. 51. 111. 112. 49. 40. + 32. 33. 40. 119. 103. 66. 34. 67. 60. 56. 63. 64. 87. 106. 131. 161. + 162. 163. 195. 138. 79. 31. 34. 58. 63. 51. 41. 47. 44. 44. 74. 108. + 97. 81. 96. 109. 114. 119. 123. 123. 125. 129. 133. 130. 133. 138. + 141. 143. 145. 148. 151. 148. 148. 149. 151. 153. 155. 157. 158. + 157. 158. 157. 153. 151. 149. 141. 132. 116. 124. 128. 126. 129. + 133. 127. 114. 101. 110. 121. 136. 160. 180. 179. 166. 163. 148. + 145. 147. 138. 133. 134. 130. 102. 57. 41. 51. 49. 49. 56. 52. 59. + 75. 72. 66. 66. 50. 51. 49. 34. 74. 156. 171. 130. 144. 93. 43. 65. + 105. 147. 150. 141. 148. 154. 155. 157. 156. 155. 153. 152. 151. + 151. 151. 149. 150. 150. 150. 150. 149. 148. 147. 147. 147. 146. + 145. 144. 142. 142. 141. 139. 135. 131. 138. 160. 185. 196. 194. + 195. 195. 196. 197. 200. 203. 206. 208. 207. 207. 206. 207. 208. + 209. 210. 211. 210. 210. 210. 209. 209. 208. 207. 207. 78. 79. 80. + 78. 75. 74. 74. 75. 67. 68. 69. 72. 79. 96. 119. 138. 149. 155. 163. + 168. 169. 169. 171. 173. 176. 180. 180. 175. 168. 157. 142. 128. 97. + 81. 73. 81. 91. 94. 95. 98. 111. 111. 115. 105. 75. 56. 69. 92. 72. + 67. 51. 42. 77. 121. 110. 69. 79. 84. 80. 73. 80. 115. 82. 119. 118. + 153. 101. 128. 92. 23. 42. 55. 45. 137. 157. 106. 45. 33. 31. 54. + 113. 89. 46. 21. 74. 88. 99. 112. 118. 132. 116. 113. 119. 134. 185. + 173. 60. 42. 30. 41. 63. 72. 61. 46. 44. 42. 44. 78. 113. 101. 81. + 93. 111. 115. 120. 123. 123. 125. 129. 133. 128. 132. 136. 139. 141. + 143. 146. 148. 146. 147. 149. 151. 153. 155. 156. 157. 156. 159. + 158. 154. 153. 152. 147. 140. 131. 132. 128. 123. 127. 134. 133. + 125. 125. 142. 162. 174. 183. 185. 175. 162. 161. 147. 144. 145. + 138. 134. 132. 123. 81. 47. 43. 55. 48. 46. 57. 59. 60. 84. 72. 74. + 67. 52. 51. 44. 36. 63. 146. 173. 131. 143. 96. 48. 66. 116. 147. + 148. 144. 149. 157. 154. 156. 156. 154. 153. 151. 151. 151. 151. + 149. 149. 150. 150. 149. 149. 148. 147. 147. 146. 146. 144. 143. + 142. 141. 141. 137. 132. 130. 142. 166. 188. 196. 193. 193. 194. + 196. 198. 201. 204. 206. 208. 207. 207. 207. 207. 208. 209. 210. + 211. 211. 210. 210. 209. 209. 208. 208. 208. 81. 80. 80. 79. 78. 77. + 77. 76. 68. 66. 68. 75. 85. 101. 123. 141. 150. 156. 164. 167. 168. + 168. 170. 172. 176. 179. 180. 175. 168. 158. 143. 129. 100. 84. 73. + 77. 84. 87. 94. 102. 108. 109. 122. 113. 67. 39. 58. 88. 75. 79. 53. + 57. 119. 100. 35. 63. 79. 81. 74. 91. 100. 114. 94. 122. 103. 129. + 124. 133. 129. 34. 37. 59. 42. 120. 156. 135. 50. 26. 38. 88. 56. + 68. 79. 75. 104. 101. 121. 145. 168. 135. 105. 112. 105. 161. 216. + 102. 34. 40. 41. 40. 48. 59. 59. 51. 45. 42. 44. 79. 115. 103. 82. + 93. 110. 114. 119. 121. 121. 122. 126. 130. 128. 132. 135. 138. 139. + 141. 143. 145. 144. 145. 148. 151. 153. 155. 156. 156. 156. 159. + 159. 155. 153. 153. 151. 146. 154. 148. 138. 129. 132. 143. 151. + 151. 143. 165. 188. 199. 197. 188. 174. 162. 157. 146. 144. 142. + 137. 136. 126. 104. 60. 44. 44. 52. 47. 44. 53. 63. 59. 91. 71. 79. + 67. 54. 54. 44. 38. 53. 132. 168. 133. 137. 91. 57. 75. 127. 145. + 146. 148. 149. 159. 156. 156. 155. 153. 152. 151. 151. 151. 151. + 149. 149. 149. 149. 149. 148. 147. 147. 147. 146. 145. 144. 143. + 142. 141. 140. 134. 130. 132. 146. 170. 189. 195. 193. 192. 194. + 197. 200. 203. 205. 207. 207. 207. 207. 207. 207. 208. 209. 210. + 211. 210. 210. 209. 209. 209. 209. 210. 211. 82. 79. 77. 77. 79. 80. + 77. 74. 68. 64. 66. 76. 88. 104. 125. 143. 153. 158. 165. 168. 168. + 169. 171. 173. 175. 179. 180. 176. 169. 159. 143. 130. 105. 87. 74. + 77. 86. 91. 97. 104. 106. 117. 137. 121. 65. 40. 63. 85. 58. 75. 68. + 93. 115. 66. 36. 69. 73. 83. 70. 97. 108. 103. 108. 122. 85. 103. + 136. 128. 147. 76. 44. 57. 58. 90. 124. 114. 57. 37. 54. 73. 50. 67. + 105. 113. 124. 116. 151. 182. 156. 111. 88. 122. 144. 187. 166. 47. + 47. 53. 54. 49. 48. 53. 56. 55. 50. 45. 44. 77. 113. 103. 84. 96. + 110. 115. 120. 123. 122. 123. 125. 128. 131. 133. 137. 139. 139. + 140. 142. 144. 142. 144. 147. 150. 153. 154. 155. 155. 156. 159. + 159. 155. 153. 154. 153. 150. 145. 143. 140. 138. 145. 159. 170. + 175. 152. 170. 190. 200. 198. 189. 175. 164. 152. 147. 144. 138. + 134. 136. 116. 80. 48. 49. 46. 46. 50. 48. 52. 66. 59. 95. 67. 79. + 65. 57. 61. 49. 40. 47. 119. 164. 138. 135. 88. 71. 94. 141. 144. + 145. 151. 148. 160. 159. 155. 154. 153. 152. 151. 151. 151. 151. + 148. 149. 149. 149. 149. 148. 147. 146. 146. 146. 145. 144. 143. + 141. 140. 140. 133. 130. 135. 152. 173. 189. 195. 195. 194. 196. + 199. 203. 206. 207. 208. 208. 206. 206. 206. 206. 207. 208. 210. + 210. 209. 209. 208. 208. 209. 210. 212. 213. 81. 76. 73. 74. 78. 79. + 75. 71. 68. 63. 65. 76. 90. 105. 126. 144. 155. 160. 167. 170. 169. + 170. 172. 174. 175. 179. 180. 176. 169. 159. 144. 130. 102. 84. 73. + 80. 92. 96. 97. 99. 106. 127. 151. 126. 68. 51. 73. 84. 76. 87. 104. + 134. 80. 37. 68. 37. 65. 82. 62. 86. 97. 84. 110. 117. 87. 103. 139. + 104. 134. 118. 69. 68. 83. 79. 102. 81. 68. 64. 72. 29. 50. 83. 131. + 133. 149. 163. 187. 174. 97. 95. 91. 139. 186. 169. 74. 46. 49. 51. + 55. 60. 62. 62. 62. 62. 56. 48. 44. 75. 112. 103. 87. 100. 112. 117. + 123. 126. 125. 125. 127. 129. 133. 135. 138. 140. 140. 140. 142. + 144. 142. 144. 147. 150. 153. 154. 155. 155. 156. 160. 160. 155. + 152. 154. 154. 151. 147. 146. 144. 145. 155. 173. 191. 201. 168. + 178. 190. 197. 196. 188. 174. 163. 149. 147. 144. 135. 132. 134. + 108. 62. 45. 56. 48. 43. 55. 56. 54. 68. 58. 96. 63. 78. 62. 58. 66. + 55. 42. 46. 113. 163. 144. 136. 88. 83. 111. 153. 144. 144. 152. + 146. 160. 162. 154. 154. 153. 151. 151. 151. 151. 151. 148. 149. + 149. 149. 149. 148. 147. 146. 146. 146. 145. 144. 142. 141. 140. + 140. 133. 132. 138. 155. 176. 189. 195. 196. 195. 198. 201. 205. + 208. 209. 209. 208. 206. 205. 205. 206. 207. 208. 209. 210. 209. + 208. 208. 208. 209. 211. 213. 215. 76. 74. 71. 71. 72. 74. 74. 73. + 64. 61. 62. 72. 87. 105. 127. 143. 155. 159. 164. 168. 169. 170. + 171. 173. 173. 177. 178. 174. 169. 160. 143. 128. 102. 87. 73. 80. + 93. 89. 87. 101. 130. 146. 114. 108. 80. 69. 58. 72. 92. 141. 85. + 67. 72. 45. 58. 51. 77. 64. 79. 60. 86. 70. 100. 106. 86. 85. 121. + 109. 158. 111. 72. 84. 107. 97. 75. 94. 49. 43. 59. 41. 81. 137. + 160. 166. 139. 182. 201. 135. 93. 85. 96. 126. 199. 71. 38. 46. 49. + 47. 51. 50. 47. 59. 68. 61. 49. 51. 36. 58. 115. 102. 95. 94. 109. + 116. 120. 121. 122. 126. 128. 126. 130. 132. 136. 139. 141. 140. + 139. 137. 136. 140. 144. 145. 146. 149. 153. 154. 153. 153. 154. + 154. 153. 151. 148. 147. 146. 153. 153. 149. 158. 181. 198. 202. + 181. 175. 193. 207. 196. 188. 178. 152. 152. 131. 155. 145. 127. + 129. 85. 42. 50. 50. 43. 47. 44. 49. 67. 57. 71. 86. 63. 78. 64. 59. + 47. 50. 39. 37. 93. 157. 144. 147. 76. 107. 124. 143. 146. 142. 149. + 156. 154. 154. 153. 153. 152. 151. 149. 148. 147. 147. 145. 147. + 148. 147. 143. 141. 143. 145. 148. 147. 145. 143. 142. 140. 140. + 139. 134. 129. 137. 162. 184. 192. 194. 196. 198. 202. 206. 209. + 209. 208. 208. 208. 206. 207. 208. 209. 209. 209. 208. 208. 211. + 211. 211. 211. 211. 211. 211. 211. 76. 73. 71. 70. 71. 73. 73. 72. + 66. 62. 63. 73. 87. 105. 126. 143. 154. 158. 164. 167. 169. 170. + 171. 173. 174. 178. 178. 175. 170. 161. 144. 128. 104. 82. 72. 80. + 82. 82. 96. 115. 138. 121. 115. 117. 64. 54. 66. 99. 118. 117. 55. + 46. 68. 59. 59. 46. 72. 64. 79. 68. 82. 70. 99. 114. 74. 85. 124. + 107. 139. 120. 97. 58. 126. 71. 62. 59. 39. 37. 61. 71. 99. 139. + 161. 142. 187. 188. 183. 98. 93. 103. 92. 178. 104. 43. 49. 41. 52. + 49. 51. 50. 47. 58. 68. 62. 49. 51. 38. 55. 112. 102. 98. 92. 108. + 115. 120. 121. 123. 127. 129. 127. 130. 133. 136. 139. 141. 141. + 139. 138. 141. 143. 145. 145. 147. 150. 152. 153. 147. 148. 149. + 150. 151. 151. 151. 151. 147. 154. 154. 151. 161. 185. 203. 209. + 182. 173. 189. 207. 198. 185. 173. 154. 148. 144. 144. 137. 134. + 113. 67. 43. 49. 51. 45. 49. 44. 49. 68. 59. 76. 90. 67. 77. 65. 64. + 55. 52. 42. 38. 90. 156. 146. 142. 80. 115. 126. 143. 146. 142. 150. + 156. 154. 154. 154. 154. 153. 152. 151. 149. 148. 148. 146. 148. + 149. 147. 144. 142. 143. 145. 145. 146. 146. 146. 144. 141. 138. + 137. 134. 130. 139. 164. 185. 193. 195. 198. 199. 202. 207. 209. + 209. 208. 208. 208. 207. 207. 207. 208. 208. 209. 209. 209. 211. + 211. 211. 211. 211. 211. 211. 211. 75. 72. 69. 68. 69. 71. 70. 70. + 66. 63. 65. 73. 87. 104. 125. 143. 153. 157. 163. 167. 169. 170. + 171. 173. 176. 179. 180. 176. 171. 161. 144. 129. 108. 78. 72. 79. + 73. 84. 114. 129. 124. 109. 132. 106. 45. 72. 91. 100. 129. 83. 40. + 44. 69. 76. 68. 60. 65. 64. 74. 72. 71. 63. 84. 107. 59. 68. 110. + 119. 132. 113. 128. 91. 165. 71. 61. 35. 50. 71. 95. 105. 98. 144. + 127. 168. 187. 195. 124. 84. 94. 91. 159. 133. 44. 31. 50. 52. 55. + 50. 51. 50. 47. 58. 68. 65. 49. 50. 41. 51. 108. 100. 102. 88. 105. + 112. 119. 121. 124. 128. 130. 128. 131. 133. 136. 139. 141. 141. + 140. 140. 141. 139. 138. 140. 143. 145. 145. 146. 150. 150. 149. + 149. 148. 148. 147. 147. 148. 154. 155. 154. 166. 189. 208. 216. + 187. 178. 190. 206. 200. 185. 170. 155. 141. 153. 133. 134. 136. 88. + 47. 43. 48. 53. 48. 52. 46. 49. 70. 62. 75. 86. 67. 71. 62. 63. 60. + 47. 45. 38. 83. 156. 149. 135. 88. 125. 129. 144. 146. 143. 151. + 156. 154. 155. 155. 154. 154. 152. 151. 150. 149. 149. 148. 149. + 149. 148. 146. 144. 145. 146. 143. 144. 147. 148. 146. 142. 137. + 134. 133. 130. 140. 165. 186. 194. 196. 199. 200. 204. 208. 210. + 209. 208. 208. 208. 209. 208. 207. 207. 207. 208. 210. 211. 211. + 211. 211. 211. 211. 211. 211. 211. 72. 70. 67. 66. 67. 68. 68. 68. + 65. 63. 65. 73. 85. 101. 123. 141. 153. 157. 163. 167. 169. 170. + 172. 173. 177. 180. 180. 177. 172. 162. 145. 129. 111. 78. 72. 76. + 74. 102. 132. 125. 108. 101. 135. 97. 56. 89. 90. 97. 114. 54. 49. + 60. 67. 76. 69. 81. 68. 72. 76. 79. 66. 60. 70. 90. 79. 60. 69. 112. + 140. 106. 137. 142. 104. 34. 32. 45. 86. 121. 123. 94. 108. 128. + 155. 177. 194. 135. 98. 94. 94. 117. 177. 46. 44. 38. 60. 71. 55. + 48. 49. 50. 48. 59. 71. 70. 53. 48. 44. 47. 104. 96. 105. 84. 100. + 109. 117. 121. 125. 129. 131. 128. 131. 133. 136. 139. 140. 141. + 141. 141. 139. 135. 134. 138. 142. 142. 142. 144. 146. 145. 145. + 144. 144. 144. 144. 144. 149. 154. 156. 157. 167. 185. 200. 206. + 193. 194. 198. 199. 196. 189. 171. 150. 134. 149. 132. 141. 122. 60. + 42. 42. 48. 54. 50. 54. 47. 50. 71. 64. 74. 81. 69. 70. 62. 63. 65. + 42. 42. 36. 74. 154. 154. 127. 96. 130. 133. 146. 146. 144. 153. + 156. 153. 156. 154. 154. 153. 152. 150. 149. 148. 148. 150. 150. + 150. 149. 147. 146. 146. 146. 143. 144. 146. 146. 144. 141. 137. + 135. 131. 129. 140. 166. 187. 194. 197. 201. 203. 206. 209. 210. + 209. 208. 208. 208. 210. 209. 207. 206. 206. 208. 211. 212. 212. + 212. 212. 212. 212. 212. 212. 212. 69. 66. 64. 63. 65. 66. 67. 66. + 63. 62. 65. 72. 83. 99. 121. 141. 153. 157. 163. 168. 170. 171. 173. + 175. 178. 180. 181. 177. 171. 161. 144. 129. 108. 77. 69. 73. 84. + 121. 135. 103. 106. 93. 122. 100. 79. 65. 57. 113. 105. 47. 59. 66. + 58. 63. 59. 79. 74. 82. 88. 88. 78. 73. 73. 80. 100. 87. 51. 70. + 122. 110. 129. 143. 88. 40. 20. 82. 111. 149. 178. 167. 145. 159. + 197. 188. 156. 101. 93. 104. 121. 168. 88. 32. 43. 39. 82. 83. 53. + 44. 47. 50. 50. 59. 72. 74. 59. 45. 45. 45. 102. 89. 106. 81. 94. + 104. 114. 120. 125. 130. 131. 128. 130. 132. 134. 137. 139. 140. + 141. 141. 142. 137. 138. 143. 145. 141. 141. 144. 135. 136. 138. + 140. 143. 145. 146. 147. 150. 153. 155. 154. 157. 165. 173. 176. + 183. 195. 189. 172. 173. 178. 160. 133. 129. 135. 137. 146. 96. 42. + 49. 41. 49. 53. 50. 55. 49. 53. 72. 64. 77. 79. 77. 77. 70. 65. 72. + 45. 38. 35. 65. 149. 158. 122. 107. 130. 138. 147. 146. 145. 155. + 157. 153. 157. 152. 152. 151. 150. 148. 147. 146. 146. 151. 150. + 149. 148. 148. 148. 147. 146. 146. 145. 144. 143. 141. 140. 138. + 137. 128. 128. 141. 167. 187. 194. 197. 202. 205. 208. 210. 210. + 209. 208. 208. 209. 211. 209. 208. 206. 207. 209. 211. 213. 212. + 212. 212. 212. 212. 212. 212. 212. 64. 62. 60. 61. 63. 65. 66. 66. + 62. 62. 65. 73. 83. 98. 122. 142. 154. 158. 164. 169. 171. 173. 175. + 177. 177. 180. 180. 177. 171. 160. 143. 127. 104. 75. 66. 81. 101. + 124. 119. 86. 97. 114. 133. 85. 62. 45. 52. 104. 111. 60. 63. 64. + 57. 62. 54. 63. 66. 85. 102. 93. 91. 85. 85. 75. 68. 111. 83. 47. + 78. 101. 117. 128. 106. 68. 44. 112. 100. 111. 169. 202. 188. 208. + 201. 174. 97. 108. 91. 106. 173. 124. 41. 39. 37. 40. 72. 92. 51. + 42. 45. 52. 51. 59. 71. 73. 68. 41. 45. 45. 101. 79. 103. 79. 88. + 99. 111. 118. 124. 130. 130. 128. 129. 130. 132. 135. 137. 139. 140. + 141. 141. 137. 139. 143. 138. 127. 124. 129. 137. 139. 140. 142. + 142. 141. 140. 139. 142. 142. 141. 138. 136. 137. 140. 142. 151. + 164. 149. 126. 134. 145. 130. 109. 129. 130. 141. 130. 69. 37. 53. + 44. 50. 52. 47. 54. 52. 56. 73. 62. 78. 71. 78. 80. 71. 57. 74. 49. + 36. 37. 56. 139. 159. 120. 120. 130. 142. 148. 145. 146. 156. 157. + 153. 157. 151. 151. 150. 149. 148. 146. 146. 145. 151. 150. 148. + 148. 148. 148. 147. 145. 146. 145. 143. 141. 140. 139. 138. 138. + 127. 128. 143. 169. 188. 195. 199. 204. 208. 210. 211. 211. 209. + 208. 208. 209. 210. 209. 208. 208. 208. 210. 211. 212. 213. 213. + 213. 213. 213. 213. 213. 213. 60. 59. 57. 58. 62. 65. 66. 66. 62. + 62. 67. 75. 84. 100. 125. 146. 155. 160. 166. 170. 173. 175. 177. + 179. 177. 180. 180. 176. 170. 159. 142. 126. 103. 74. 71. 102. 122. + 111. 94. 89. 103. 138. 147. 73. 43. 51. 77. 64. 93. 67. 64. 65. 66. + 69. 59. 53. 54. 86. 121. 97. 104. 93. 98. 74. 52. 90. 105. 79. 75. + 91. 97. 115. 103. 94. 125. 163. 139. 131. 167. 191. 213. 202. 189. + 103. 105. 92. 110. 134. 163. 46. 56. 33. 48. 43. 45. 89. 52. 42. 46. + 53. 51. 56. 67. 69. 77. 37. 44. 46. 102. 71. 100. 78. 83. 95. 108. + 117. 123. 129. 130. 127. 127. 128. 130. 133. 135. 138. 139. 140. + 141. 139. 140. 140. 126. 106. 99. 104. 120. 122. 125. 127. 127. 125. + 122. 119. 119. 117. 114. 112. 111. 114. 119. 125. 127. 129. 108. 95. + 111. 118. 109. 107. 132. 138. 139. 95. 52. 44. 44. 49. 51. 51. 44. + 52. 53. 59. 73. 59. 82. 64. 75. 79. 67. 45. 73. 56. 40. 43. 49. 128. + 157. 121. 135. 133. 146. 149. 145. 147. 158. 157. 153. 158. 152. + 152. 151. 149. 148. 147. 146. 146. 151. 149. 147. 147. 148. 148. + 146. 144. 144. 144. 144. 143. 141. 139. 137. 136. 128. 130. 146. + 172. 191. 198. 202. 208. 210. 211. 212. 211. 209. 208. 208. 209. + 209. 209. 209. 210. 210. 210. 211. 211. 213. 213. 213. 213. 213. + 213. 213. 213. 58. 56. 56. 57. 61. 65. 66. 67. 63. 64. 69. 77. 86. + 103. 128. 149. 156. 160. 167. 171. 174. 176. 178. 180. 176. 179. + 179. 175. 169. 158. 141. 125. 105. 76. 78. 122. 137. 98. 77. 100. + 134. 134. 136. 87. 55. 57. 87. 37. 52. 57. 62. 68. 71. 70. 63. 50. + 52. 95. 142. 106. 115. 99. 109. 78. 91. 53. 85. 121. 115. 97. 72. + 91. 80. 79. 137. 121. 121. 156. 196. 204. 210. 195. 136. 93. 99. + 110. 104. 191. 93. 38. 45. 45. 62. 40. 39. 76. 54. 43. 47. 54. 51. + 54. 63. 65. 82. 35. 44. 48. 103. 65. 98. 77. 80. 93. 107. 116. 123. + 128. 129. 126. 126. 127. 129. 132. 134. 137. 138. 139. 147. 145. + 146. 142. 121. 94. 85. 90. 78. 83. 91. 99. 105. 107. 107. 107. 96. + 93. 91. 92. 95. 102. 114. 123. 126. 116. 92. 92. 114. 114. 109. 126. + 135. 150. 134. 65. 45. 52. 33. 54. 52. 50. 42. 51. 54. 61. 74. 57. + 90. 66. 78. 82. 68. 42. 78. 67. 44. 48. 46. 120. 154. 123. 145. 137. + 147. 150. 145. 148. 158. 158. 153. 158. 153. 153. 152. 151. 149. + 148. 147. 147. 151. 148. 146. 146. 148. 148. 146. 143. 141. 143. + 145. 146. 144. 140. 136. 133. 129. 132. 148. 175. 194. 200. 205. + 211. 211. 212. 213. 211. 209. 208. 208. 209. 208. 209. 210. 211. + 211. 211. 211. 210. 213. 213. 213. 213. 213. 213. 213. 213. 54. 54. + 55. 57. 59. 62. 64. 66. 64. 61. 72. 86. 91. 107. 130. 142. 155. 160. + 168. 173. 175. 176. 176. 177. 178. 178. 182. 177. 164. 159. 145. + 121. 107. 70. 129. 141. 96. 78. 79. 122. 147. 138. 118. 79. 52. 82. + 54. 50. 33. 73. 56. 67. 74. 60. 79. 60. 57. 93. 148. 116. 107. 94. + 93. 104. 102. 95. 80. 105. 135. 94. 54. 78. 61. 93. 129. 136. 142. + 137. 198. 218. 208. 188. 104. 101. 79. 126. 182. 131. 44. 45. 47. + 48. 45. 43. 50. 59. 60. 48. 45. 54. 61. 58. 58. 64. 79. 61. 38. 48. + 101. 64. 97. 81. 80. 91. 106. 116. 120. 121. 124. 127. 125. 126. + 128. 131. 134. 136. 138. 140. 147. 148. 148. 142. 133. 125. 122. + 121. 110. 106. 103. 106. 112. 118. 121. 121. 117. 117. 116. 116. + 118. 122. 127. 131. 137. 154. 136. 120. 138. 140. 130. 141. 150. + 143. 95. 46. 42. 49. 48. 53. 53. 47. 40. 55. 61. 78. 51. 64. 83. 68. + 71. 84. 63. 49. 72. 77. 42. 47. 40. 95. 161. 135. 148. 138. 150. + 146. 146. 151. 154. 153. 153. 155. 152. 153. 153. 153. 153. 152. + 151. 150. 148. 148. 147. 147. 147. 147. 146. 146. 146. 145. 144. + 144. 143. 140. 135. 132. 124. 130. 156. 183. 193. 201. 209. 209. + 212. 211. 210. 209. 209. 209. 209. 209. 210. 210. 209. 210. 211. + 213. 215. 217. 213. 213. 213. 213. 213. 213. 213. 214. 54. 55. 56. + 57. 59. 62. 64. 65. 62. 60. 73. 86. 91. 106. 130. 142. 155. 160. + 167. 173. 175. 176. 176. 177. 180. 179. 182. 175. 162. 156. 143. + 119. 102. 141. 139. 84. 84. 96. 85. 125. 133. 120. 118. 75. 61. 64. + 69. 53. 49. 56. 50. 53. 74. 60. 67. 82. 52. 87. 158. 121. 76. 89. + 94. 107. 111. 93. 95. 91. 74. 89. 101. 79. 92. 119. 159. 141. 134. + 122. 162. 219. 208. 118. 106. 92. 126. 175. 161. 65. 48. 49. 51. 52. + 47. 43. 48. 56. 59. 48. 44. 52. 58. 57. 58. 63. 73. 61. 41. 48. 93. + 59. 91. 80. 76. 87. 102. 113. 117. 119. 121. 124. 125. 126. 128. + 131. 134. 136. 138. 139. 145. 147. 147. 144. 138. 132. 128. 126. + 124. 123. 122. 121. 121. 123. 127. 130. 139. 146. 155. 160. 163. + 169. 179. 187. 180. 180. 153. 132. 142. 148. 141. 144. 145. 115. 70. + 43. 43. 45. 46. 53. 48. 44. 47. 53. 59. 66. 49. 67. 88. 68. 77. 82. + 61. 53. 66. 79. 44. 48. 42. 95. 162. 139. 150. 141. 151. 147. 147. + 152. 155. 153. 153. 155. 152. 153. 153. 153. 153. 152. 151. 150. + 148. 148. 148. 147. 147. 147. 146. 146. 146. 145. 144. 144. 143. + 140. 135. 131. 124. 131. 158. 185. 195. 203. 211. 210. 212. 212. + 211. 210. 209. 209. 210. 210. 210. 210. 211. 211. 212. 214. 215. + 216. 213. 213. 213. 213. 213. 213. 212. 212. 55. 55. 56. 57. 59. 61. + 63. 64. 59. 59. 74. 87. 90. 105. 129. 142. 153. 159. 167. 172. 175. + 176. 177. 178. 181. 180. 182. 176. 163. 159. 148. 125. 126. 148. + 109. 65. 81. 88. 97. 147. 119. 104. 118. 75. 75. 61. 103. 66. 57. + 38. 45. 46. 86. 63. 57. 99. 55. 95. 168. 126. 54. 72. 89. 101. 110. + 104. 92. 76. 64. 69. 88. 105. 118. 130. 166. 138. 129. 127. 149. + 215. 145. 99. 112. 115. 180. 171. 87. 48. 50. 51. 54. 54. 48. 42. + 44. 51. 57. 48. 44. 51. 56. 56. 58. 63. 68. 61. 46. 48. 83. 55. 85. + 79. 70. 81. 96. 108. 114. 116. 118. 119. 124. 125. 126. 128. 131. + 133. 134. 135. 143. 144. 145. 146. 145. 141. 135. 131. 127. 130. + 130. 127. 123. 123. 128. 133. 143. 154. 167. 173. 173. 174. 181. + 188. 196. 181. 153. 134. 137. 149. 148. 140. 134. 80. 43. 43. 46. + 44. 48. 53. 42. 40. 55. 50. 59. 52. 48. 70. 93. 67. 84. 79. 61. 60. + 58. 84. 46. 48. 44. 94. 161. 144. 152. 145. 153. 149. 148. 153. 156. + 154. 154. 156. 153. 153. 153. 153. 153. 152. 151. 151. 149. 148. + 148. 148. 147. 147. 146. 146. 145. 144. 143. 143. 142. 139. 134. + 130. 124. 132. 160. 188. 198. 206. 213. 211. 212. 212. 211. 210. + 210. 210. 210. 211. 211. 212. 213. 213. 214. 214. 214. 214. 213. + 212. 212. 211. 211. 210. 210. 210. 55. 55. 56. 56. 58. 60. 61. 62. + 56. 58. 75. 89. 90. 103. 128. 141. 152. 158. 166. 172. 175. 176. + 177. 178. 180. 179. 182. 177. 168. 166. 157. 136. 139. 91. 68. 81. + 73. 87. 134. 146. 107. 101. 106. 72. 73. 78. 131. 69. 49. 37. 42. + 56. 104. 66. 61. 97. 66. 123. 161. 122. 74. 55. 81. 88. 95. 107. + 104. 91. 80. 72. 82. 108. 136. 133. 149. 136. 124. 144. 174. 182. + 94. 118. 128. 180. 173. 109. 41. 61. 48. 50. 54. 55. 49. 42. 42. 48. + 57. 50. 47. 52. 56. 57. 59. 64. 69. 64. 49. 49. 78. 61. 81. 78. 66. + 76. 91. 103. 110. 114. 115. 116. 120. 121. 122. 124. 127. 129. 130. + 131. 141. 141. 142. 146. 148. 146. 139. 133. 125. 126. 127. 125. + 123. 124. 128. 131. 134. 143. 153. 158. 156. 153. 152. 153. 165. + 151. 139. 132. 134. 149. 151. 136. 112. 59. 36. 46. 47. 48. 54. 50. + 45. 39. 59. 47. 61. 46. 49. 72. 94. 66. 89. 75. 62. 67. 54. 91. 49. + 47. 46. 90. 159. 149. 153. 148. 154. 150. 150. 154. 157. 155. 155. + 157. 153. 153. 154. 154. 153. 153. 152. 151. 150. 149. 149. 148. + 147. 147. 146. 146. 145. 144. 143. 142. 141. 138. 133. 129. 124. + 132. 162. 192. 203. 209. 215. 213. 213. 212. 211. 211. 211. 211. + 212. 212. 212. 213. 214. 215. 215. 214. 212. 211. 210. 210. 209. + 208. 208. 207. 206. 206. 55. 54. 55. 55. 56. 57. 59. 60. 53. 58. 77. + 90. 89. 100. 125. 140. 150. 156. 164. 171. 175. 176. 178. 179. 180. + 180. 183. 178. 168. 167. 158. 136. 113. 67. 63. 76. 69. 119. 163. + 110. 103. 106. 86. 64. 57. 103. 133. 55. 40. 51. 41. 71. 106. 63. + 76. 87. 73. 150. 139. 108. 117. 57. 85. 89. 73. 87. 126. 118. 80. + 106. 131. 90. 145. 148. 144. 148. 113. 147. 202. 137. 120. 125. 174. + 206. 109. 63. 57. 49. 48. 51. 56. 58. 53. 46. 46. 52. 55. 52. 51. + 55. 58. 59. 61. 64. 73. 67. 52. 49. 75. 71. 80. 76. 64. 73. 86. 98. + 106. 110. 112. 113. 118. 119. 121. 123. 126. 128. 129. 130. 139. + 139. 141. 144. 147. 145. 138. 132. 132. 129. 126. 126. 128. 129. + 129. 127. 131. 135. 141. 148. 152. 151. 146. 142. 133. 133. 139. + 143. 145. 152. 147. 127. 82. 51. 42. 48. 44. 51. 57. 45. 53. 42. 58. + 47. 64. 48. 52. 76. 90. 66. 87. 74. 67. 70. 55. 96. 51. 45. 48. 86. + 156. 153. 152. 149. 155. 151. 150. 155. 157. 155. 155. 156. 153. + 154. 154. 154. 154. 153. 152. 151. 151. 150. 150. 149. 148. 147. + 146. 146. 145. 144. 143. 142. 140. 137. 131. 127. 122. 132. 164. + 195. 206. 212. 217. 214. 213. 212. 212. 212. 212. 212. 213. 214. + 213. 214. 215. 215. 214. 213. 211. 209. 207. 207. 206. 206. 205. + 205. 204. 204. 53. 53. 53. 53. 54. 55. 56. 56. 52. 59. 80. 92. 88. + 97. 122. 137. 149. 155. 163. 170. 175. 177. 178. 180. 182. 181. 183. + 177. 165. 161. 149. 126. 95. 78. 66. 66. 98. 141. 135. 95. 111. 112. + 73. 60. 53. 126. 118. 42. 42. 61. 42. 83. 87. 56. 79. 81. 80. 165. + 121. 95. 134. 87. 101. 108. 61. 71. 98. 113. 113. 123. 128. 112. + 124. 153. 144. 155. 107. 148. 215. 127. 151. 156. 216. 140. 64. 50. + 56. 52. 51. 54. 59. 61. 57. 50. 51. 57. 53. 53. 55. 57. 59. 61. 62. + 63. 72. 68. 55. 50. 70. 77. 78. 76. 64. 70. 80. 91. 100. 106. 108. + 109. 117. 118. 121. 123. 126. 129. 131. 132. 135. 137. 139. 142. + 143. 142. 138. 134. 137. 132. 127. 127. 129. 129. 125. 121. 126. + 125. 126. 131. 137. 138. 133. 127. 127. 139. 147. 150. 154. 147. + 125. 103. 57. 50. 48. 45. 42. 50. 53. 44. 61. 48. 55. 51. 61. 53. + 53. 82. 83. 71. 82. 75. 73. 68. 57. 95. 56. 45. 51. 82. 153. 156. + 151. 150. 155. 151. 150. 155. 157. 155. 154. 156. 154. 154. 155. + 155. 154. 153. 152. 152. 151. 151. 150. 149. 148. 147. 146. 146. + 145. 143. 142. 141. 139. 136. 130. 126. 121. 131. 165. 198. 209. + 215. 218. 214. 213. 213. 212. 212. 213. 213. 214. 215. 215. 215. + 214. 213. 212. 210. 209. 208. 205. 205. 205. 205. 205. 205. 205. + 205. 52. 52. 51. 51. 51. 52. 53. 54. 51. 60. 82. 94. 87. 94. 119. + 135. 148. 154. 163. 170. 174. 177. 179. 180. 182. 181. 184. 177. + 164. 158. 145. 121. 100. 78. 66. 71. 123. 139. 97. 105. 113. 101. + 64. 57. 65. 136. 98. 41. 48. 51. 49. 97. 65. 52. 62. 76. 98. 173. + 126. 92. 104. 127. 111. 124. 75. 74. 63. 97. 147. 124. 97. 131. 91. + 136. 130. 138. 114. 162. 205. 146. 160. 190. 170. 65. 52. 48. 45. + 62. 53. 55. 59. 61. 55. 49. 51. 57. 48. 52. 56. 59. 60. 61. 61. 60. + 65. 66. 58. 49. 62. 75. 73. 78. 64. 68. 75. 84. 94. 100. 104. 105. + 113. 114. 117. 120. 124. 127. 130. 131. 131. 134. 138. 140. 140. + 140. 139. 139. 135. 133. 131. 129. 128. 126. 125. 123. 122. 120. + 119. 119. 121. 122. 121. 120. 137. 152. 147. 142. 151. 135. 96. 75. + 47. 51. 46. 42. 46. 48. 48. 52. 65. 54. 52. 56. 54. 55. 52. 90. 79. + 80. 77. 78. 78. 61. 59. 90. 61. 48. 55. 81. 152. 160. 151. 152. 155. + 151. 150. 154. 156. 154. 153. 155. 154. 154. 155. 155. 154. 154. + 153. 152. 152. 152. 151. 150. 148. 147. 146. 146. 144. 143. 142. + 141. 139. 135. 129. 125. 119. 130. 165. 199. 211. 216. 219. 213. + 213. 213. 213. 213. 213. 214. 215. 216. 216. 215. 213. 211. 209. + 208. 207. 207. 205. 205. 206. 207. 207. 208. 209. 209. 51. 51. 50. + 50. 50. 50. 51. 52. 51. 61. 84. 95. 86. 92. 117. 133. 147. 154. 162. + 170. 174. 177. 179. 180. 180. 180. 184. 179. 166. 161. 147. 123. + 101. 71. 75. 72. 113. 139. 97. 106. 104. 78. 53. 49. 75. 133. 82. + 43. 50. 35. 57. 111. 54. 52. 40. 71. 120. 180. 142. 96. 64. 152. + 111. 129. 102. 79. 74. 102. 131. 135. 119. 105. 76. 121. 112. 114. + 124. 177. 182. 158. 181. 182. 72. 51. 42. 50. 68. 42. 52. 53. 56. + 57. 51. 45. 47. 54. 45. 51. 56. 59. 60. 60. 59. 57. 57. 64. 60. 49. + 54. 71. 69. 79. 63. 66. 71. 80. 89. 96. 101. 102. 107. 109. 112. + 116. 120. 123. 126. 128. 128. 133. 138. 140. 139. 139. 141. 144. + 131. 134. 137. 135. 131. 130. 132. 135. 127. 128. 129. 128. 129. + 132. 139. 144. 148. 161. 142. 131. 147. 128. 81. 62. 48. 53. 42. 41. + 53. 48. 45. 63. 64. 58. 52. 61. 47. 55. 50. 96. 77. 86. 74. 80. 82. + 56. 60. 85. 65. 50. 58. 81. 152. 163. 152. 153. 155. 151. 150. 153. + 155. 153. 152. 154. 154. 155. 155. 155. 155. 154. 153. 152. 153. + 152. 151. 150. 148. 147. 146. 146. 144. 143. 141. 140. 138. 134. + 129. 125. 117. 130. 165. 200. 212. 216. 219. 213. 213. 213. 213. + 213. 214. 215. 216. 216. 217. 215. 212. 209. 207. 206. 206. 206. + 206. 207. 207. 209. 210. 211. 212. 212. 52. 51. 50. 50. 50. 50. 49. + 48. 47. 75. 99. 102. 99. 107. 122. 131. 140. 148. 159. 169. 174. + 176. 176. 177. 178. 181. 180. 176. 171. 161. 145. 130. 99. 78. 64. + 74. 119. 131. 99. 98. 87. 81. 57. 52. 78. 113. 56. 51. 45. 35. 69. + 81. 63. 56. 51. 54. 127. 171. 129. 131. 82. 115. 142. 130. 102. 110. + 124. 85. 94. 121. 128. 97. 67. 129. 128. 114. 126. 173. 180. 187. + 204. 106. 43. 51. 60. 47. 45. 55. 53. 55. 59. 60. 54. 47. 49. 55. + 50. 55. 56. 53. 54. 59. 59. 55. 57. 65. 64. 54. 52. 62. 69. 67. 65. + 63. 66. 75. 82. 87. 96. 106. 103. 108. 114. 118. 125. 131. 130. 125. + 134. 134. 136. 138. 140. 140. 137. 135. 139. 136. 132. 132. 135. + 140. 143. 145. 145. 152. 156. 153. 151. 153. 154. 153. 154. 152. + 139. 144. 145. 96. 56. 71. 52. 47. 42. 42. 46. 52. 55. 56. 65. 49. + 50. 50. 50. 45. 51. 94. 83. 72. 86. 80. 65. 65. 67. 79. 68. 48. 60. + 70. 144. 170. 154. 157. 145. 148. 153. 156. 156. 155. 155. 155. 154. + 154. 154. 153. 153. 153. 152. 152. 152. 151. 149. 149. 149. 147. + 144. 142. 143. 142. 141. 140. 138. 134. 127. 122. 120. 125. 169. + 198. 210. 220. 216. 220. 214. 214. 214. 215. 215. 216. 216. 217. + 212. 211. 211. 210. 210. 210. 211. 212. 208. 209. 210. 210. 209. + 209. 210. 211. 51. 50. 50. 50. 50. 50. 49. 49. 52. 80. 103. 104. 99. + 107. 123. 133. 140. 148. 160. 169. 174. 176. 176. 176. 177. 180. + 180. 176. 170. 160. 144. 129. 103. 80. 66. 72. 111. 126. 102. 105. + 87. 80. 65. 81. 71. 97. 60. 46. 43. 45. 80. 80. 58. 61. 60. 57. 120. + 151. 133. 111. 110. 107. 145. 124. 113. 110. 103. 76. 93. 116. 132. + 98. 58. 120. 97. 125. 111. 210. 232. 196. 126. 72. 42. 52. 58. 52. + 51. 52. 47. 50. 55. 57. 52. 46. 50. 57. 51. 55. 55. 50. 49. 54. 58. + 58. 56. 63. 62. 53. 50. 59. 65. 64. 66. 60. 62. 72. 77. 78. 89. 103. + 107. 112. 116. 117. 120. 126. 129. 127. 134. 135. 136. 138. 140. + 140. 139. 138. 140. 142. 143. 143. 142. 144. 149. 153. 157. 163. + 165. 161. 157. 158. 157. 155. 158. 149. 144. 149. 128. 70. 44. 68. + 48. 44. 41. 43. 48. 54. 57. 59. 65. 51. 54. 52. 52. 46. 54. 99. 87. + 76. 90. 85. 70. 72. 73. 85. 66. 50. 57. 68. 144. 171. 157. 160. 143. + 149. 155. 158. 157. 155. 155. 156. 154. 154. 153. 153. 153. 152. + 152. 152. 153. 151. 150. 149. 149. 148. 145. 142. 143. 142. 141. + 140. 138. 133. 127. 122. 118. 125. 171. 200. 211. 221. 216. 219. + 215. 215. 215. 214. 214. 214. 214. 214. 213. 212. 211. 211. 210. + 211. 211. 211. 214. 214. 213. 212. 209. 207. 207. 207. 49. 49. 49. + 49. 50. 50. 50. 50. 59. 86. 107. 106. 99. 106. 123. 135. 141. 149. + 160. 169. 174. 176. 176. 176. 176. 179. 179. 175. 169. 159. 143. + 128. 104. 81. 68. 68. 98. 117. 103. 110. 83. 79. 72. 104. 73. 76. + 63. 44. 37. 48. 84. 74. 48. 58. 62. 58. 107. 134. 121. 95. 122. 106. + 139. 127. 108. 115. 103. 81. 80. 82. 129. 116. 110. 131. 77. 127. + 100. 171. 212. 135. 60. 47. 46. 51. 50. 53. 56. 49. 47. 50. 56. 57. + 51. 45. 49. 58. 50. 54. 54. 47. 44. 48. 56. 61. 54. 61. 60. 52. 49. + 55. 60. 60. 66. 56. 57. 69. 71. 66. 76. 94. 96. 103. 109. 110. 114. + 124. 132. 135. 133. 134. 135. 136. 138. 139. 140. 141. 140. 147. + 154. 154. 151. 150. 155. 160. 167. 172. 172. 167. 163. 162. 160. + 156. 160. 145. 151. 151. 103. 45. 40. 67. 43. 42. 42. 44. 50. 55. + 59. 61. 63. 53. 58. 55. 53. 48. 58. 104. 86. 75. 89. 83. 69. 73. 74. + 84. 67. 57. 56. 65. 144. 169. 158. 161. 140. 148. 156. 159. 156. + 153. 153. 155. 153. 153. 153. 152. 152. 152. 151. 151. 153. 152. + 150. 150. 149. 148. 145. 143. 142. 141. 140. 140. 137. 133. 126. + 121. 115. 127. 175. 204. 213. 221. 216. 218. 215. 215. 214. 214. + 213. 212. 211. 211. 214. 213. 212. 211. 211. 210. 211. 211. 205. + 204. 204. 204. 203. 203. 203. 202. 47. 48. 49. 49. 49. 49. 50. 52. + 63. 89. 108. 105. 98. 105. 123. 135. 141. 149. 160. 169. 174. 175. + 176. 176. 176. 178. 178. 174. 168. 159. 142. 127. 102. 79. 69. 66. + 87. 108. 101. 105. 76. 76. 68. 94. 95. 62. 62. 48. 37. 46. 81. 73. + 45. 52. 61. 65. 97. 128. 99. 86. 100. 104. 121. 136. 115. 129. 113. + 99. 85. 66. 130. 130. 123. 135. 75. 96. 105. 131. 191. 87. 57. 50. + 51. 50. 44. 49. 54. 49. 54. 57. 62. 61. 52. 44. 48. 57. 47. 52. 54. + 49. 43. 44. 52. 59. 54. 59. 60. 53. 50. 54. 57. 58. 66. 54. 56. 69. + 68. 56. 60. 78. 82. 92. 100. 103. 107. 117. 127. 133. 130. 131. 133. + 134. 136. 138. 141. 144. 141. 148. 156. 160. 159. 158. 159. 162. + 168. 172. 172. 168. 165. 165. 163. 158. 156. 145. 157. 143. 79. 40. + 53. 67. 43. 43. 44. 47. 51. 56. 59. 61. 60. 53. 60. 56. 52. 49. 61. + 108. 87. 77. 90. 81. 68. 73. 72. 79. 69. 67. 56. 63. 145. 166. 158. + 160. 138. 147. 156. 158. 155. 151. 152. 154. 152. 152. 152. 152. + 151. 151. 151. 150. 153. 151. 150. 149. 149. 148. 145. 142. 142. + 141. 140. 139. 137. 132. 125. 121. 114. 130. 181. 208. 214. 222. + 215. 216. 213. 212. 212. 212. 212. 212. 212. 212. 215. 214. 213. + 211. 210. 210. 210. 210. 209. 208. 208. 208. 209. 209. 208. 206. 46. + 48. 50. 50. 48. 48. 50. 52. 62. 86. 103. 101. 96. 106. 123. 134. + 142. 150. 160. 169. 174. 175. 175. 175. 176. 178. 178. 174. 168. + 159. 142. 127. 101. 77. 73. 70. 85. 106. 99. 95. 66. 72. 59. 64. + 122. 62. 57. 56. 48. 44. 77. 79. 52. 51. 60. 74. 99. 126. 96. 67. + 71. 78. 100. 130. 140. 138. 115. 115. 114. 90. 137. 124. 112. 154. + 87. 76. 106. 124. 160. 70. 78. 56. 49. 53. 49. 49. 52. 49. 55. 59. + 64. 62. 52. 44. 49. 59. 44. 49. 54. 53. 47. 44. 48. 55. 54. 59. 60. + 56. 52. 54. 57. 58. 65. 55. 57. 70. 68. 53. 50. 59. 72. 83. 93. 97. + 101. 109. 117. 121. 128. 130. 133. 135. 136. 139. 144. 148. 145. + 148. 154. 160. 165. 166. 164. 162. 165. 168. 169. 167. 167. 169. + 167. 162. 150. 148. 157. 124. 58. 46. 66. 58. 48. 48. 49. 50. 52. + 55. 59. 61. 56. 52. 59. 54. 51. 51. 63. 108. 92. 83. 94. 84. 70. 76. + 75. 79. 66. 73. 53. 61. 148. 166. 161. 162. 141. 148. 156. 159. 156. + 154. 154. 155. 152. 151. 151. 151. 150. 150. 150. 150. 152. 151. + 149. 149. 148. 147. 144. 142. 141. 140. 139. 138. 136. 131. 125. + 120. 116. 136. 189. 212. 215. 222. 215. 215. 209. 209. 210. 211. + 212. 213. 214. 214. 215. 214. 212. 211. 209. 208. 208. 208. 208. + 207. 206. 207. 207. 205. 200. 196. 45. 48. 51. 50. 47. 46. 48. 51. + 58. 79. 96. 97. 97. 109. 124. 132. 143. 150. 161. 169. 174. 175. + 175. 174. 176. 179. 179. 175. 169. 159. 143. 128. 103. 76. 74. 75. + 87. 109. 97. 80. 56. 65. 54. 48. 129. 71. 51. 62. 55. 43. 71. 76. + 52. 48. 54. 67. 109. 124. 115. 54. 58. 51. 87. 107. 131. 129. 125. + 127. 126. 102. 132. 121. 136. 161. 89. 95. 99. 95. 75. 61. 77. 51. + 45. 58. 58. 53. 52. 49. 52. 57. 62. 61. 51. 44. 52. 64. 45. 48. 54. + 58. 53. 47. 47. 52. 53. 57. 59. 58. 55. 54. 56. 59. 63. 57. 59. 68. + 69. 59. 49. 47. 54. 65. 78. 86. 96. 108. 118. 121. 123. 128. 133. + 136. 137. 139. 144. 149. 148. 149. 153. 159. 166. 169. 168. 165. + 165. 167. 168. 166. 168. 171. 169. 163. 146. 151. 151. 104. 45. 49. + 67. 47. 53. 53. 54. 53. 53. 55. 60. 63. 54. 50. 57. 51. 51. 54. 66. + 108. 91. 83. 94. 82. 69. 77. 75. 76. 60. 77. 51. 60. 153. 168. 164. + 165. 146. 149. 154. 157. 157. 156. 156. 156. 151. 151. 150. 150. + 150. 149. 149. 149. 151. 149. 148. 147. 147. 146. 143. 140. 140. + 139. 138. 137. 135. 130. 124. 119. 120. 143. 196. 216. 216. 222. + 216. 215. 208. 209. 210. 211. 213. 214. 215. 216. 215. 214. 212. + 209. 208. 206. 206. 205. 201. 200. 200. 202. 202. 197. 189. 182. 46. + 49. 52. 50. 46. 44. 47. 50. 55. 73. 89. 93. 100. 115. 127. 132. 143. + 150. 161. 169. 174. 174. 174. 174. 177. 180. 180. 176. 170. 160. + 144. 129. 105. 72. 70. 73. 86. 109. 92. 64. 50. 56. 59. 62. 109. 81. + 45. 64. 60. 48. 70. 67. 47. 49. 48. 48. 113. 130. 129. 74. 54. 59. + 83. 90. 109. 109. 129. 129. 129. 112. 127. 121. 141. 139. 105. 97. + 94. 89. 49. 72. 60. 46. 48. 58. 57. 54. 54. 49. 54. 59. 65. 63. 52. + 45. 53. 66. 49. 49. 54. 59. 57. 50. 48. 51. 51. 54. 58. 59. 56. 54. + 56. 59. 62. 59. 58. 63. 70. 68. 56. 44. 42. 50. 60. 70. 84. 101. + 112. 115. 113. 120. 127. 131. 132. 134. 139. 143. 144. 147. 151. + 156. 160. 163. 167. 169. 168. 169. 168. 165. 166. 168. 164. 157. + 144. 149. 141. 92. 43. 47. 63. 49. 56. 57. 56. 54. 54. 56. 62. 68. + 54. 50. 55. 50. 53. 59. 69. 108. 88. 80. 91. 79. 69. 80. 78. 77. 61. + 85. 52. 60. 155. 165. 162. 161. 145. 145. 145. 148. 152. 154. 152. + 150. 150. 150. 150. 149. 149. 149. 148. 148. 149. 148. 146. 146. + 146. 144. 141. 139. 140. 139. 138. 137. 134. 130. 123. 118. 125. + 149. 203. 219. 216. 222. 216. 215. 210. 210. 211. 212. 213. 214. + 215. 215. 214. 213. 211. 208. 206. 204. 203. 203. 205. 201. 197. + 192. 183. 169. 151. 138. 46. 50. 53. 50. 46. 43. 46. 50. 52. 69. 84. + 92. 103. 119. 130. 132. 143. 151. 161. 169. 174. 174. 174. 174. 178. + 181. 180. 176. 171. 161. 145. 130. 104. 67. 64. 67. 81. 106. 87. 52. + 47. 50. 66. 85. 85. 87. 43. 63. 66. 59. 77. 64. 46. 56. 51. 37. 110. + 140. 128. 108. 49. 89. 82. 87. 113. 95. 117. 122. 144. 143. 134. + 113. 135. 150. 167. 73. 84. 116. 88. 61. 50. 49. 55. 56. 48. 50. 55. + 50. 61. 66. 71. 67. 54. 46. 53. 66. 53. 50. 52. 58. 58. 52. 50. 52. + 49. 52. 56. 58. 56. 54. 55. 59. 61. 60. 57. 59. 69. 75. 64. 46. 49. + 52. 54. 59. 70. 84. 93. 95. 103. 111. 120. 124. 125. 127. 131. 136. + 137. 143. 149. 151. 151. 155. 163. 170. 170. 170. 167. 163. 162. + 162. 157. 149. 143. 146. 134. 90. 48. 46. 60. 58. 57. 58. 57. 55. + 54. 58. 65. 71. 55. 50. 54. 49. 55. 62. 71. 108. 90. 83. 94. 83. 75. + 87. 86. 85. 67. 94. 56. 62. 156. 161. 156. 153. 141. 138. 136. 139. + 145. 148. 147. 143. 150. 150. 149. 149. 149. 148. 148. 148. 148. + 147. 145. 145. 145. 143. 140. 138. 139. 138. 137. 136. 134. 129. + 123. 118. 128. 153. 206. 221. 216. 222. 217. 216. 212. 213. 213. + 213. 213. 213. 214. 214. 214. 212. 210. 207. 205. 203. 202. 202. + 195. 186. 171. 153. 130. 101. 70. 50. 43. 45. 47. 46. 44. 43. 45. + 48. 50. 60. 77. 93. 101. 109. 122. 136. 147. 154. 163. 168. 170. + 171. 173. 175. 173. 178. 180. 176. 169. 158. 143. 129. 100. 61. 55. + 78. 122. 126. 78. 116. 49. 39. 81. 88. 71. 71. 59. 64. 54. 73. 71. + 48. 58. 41. 55. 41. 77. 171. 122. 118. 62. 82. 72. 72. 91. 110. 114. + 84. 118. 138. 98. 127. 125. 166. 142. 127. 137. 134. 118. 74. 45. + 47. 48. 48. 53. 55. 55. 54. 53. 71. 69. 71. 40. 49. 52. 72. 53. 49. + 51. 56. 56. 50. 49. 52. 41. 47. 54. 57. 58. 58. 61. 65. 64. 65. 61. + 59. 64. 72. 72. 65. 58. 54. 54. 59. 60. 58. 61. 68. 73. 81. 92. 99. + 104. 111. 120. 127. 133. 136. 141. 145. 148. 151. 154. 157. 167. + 161. 156. 155. 158. 156. 149. 142. 138. 142. 124. 85. 55. 49. 51. + 48. 50. 59. 60. 52. 51. 59. 64. 61. 62. 54. 50. 53. 53. 58. 79. 103. + 97. 87. 89. 85. 71. 81. 92. 78. 70. 81. 64. 79. 151. 164. 163. 149. + 139. 126. 120. 129. 137. 137. 137. 142. 145. 146. 146. 147. 149. + 151. 152. 154. 149. 149. 148. 147. 145. 143. 141. 140. 139. 136. + 135. 137. 134. 124. 117. 115. 135. 176. 207. 217. 220. 216. 211. + 215. 208. 212. 213. 209. 209. 212. 214. 212. 204. 210. 211. 205. + 199. 197. 192. 184. 171. 145. 106. 72. 52. 44. 42. 41. 47. 49. 50. + 48. 45. 42. 42. 44. 48. 59. 76. 89. 94. 100. 115. 131. 146. 154. + 163. 169. 171. 171. 173. 175. 178. 180. 179. 174. 168. 156. 137. + 120. 90. 77. 79. 148. 189. 93. 114. 133. 49. 38. 65. 80. 67. 60. 57. + 60. 59. 63. 55. 47. 48. 39. 51. 37. 74. 145. 136. 145. 82. 102. 95. + 44. 78. 121. 153. 99. 82. 114. 105. 118. 153. 148. 142. 138. 137. + 162. 169. 120. 52. 50. 53. 63. 33. 48. 53. 49. 60. 78. 75. 73. 42. + 49. 53. 70. 51. 48. 50. 54. 54. 49. 48. 51. 46. 47. 50. 55. 59. 61. + 61. 60. 60. 60. 57. 55. 61. 72. 75. 73. 64. 64. 70. 79. 85. 86. 90. + 96. 97. 103. 109. 112. 112. 114. 120. 124. 135. 139. 145. 149. 151. + 153. 156. 158. 160. 157. 154. 154. 154. 151. 144. 139. 130. 135. + 116. 72. 40. 42. 61. 73. 60. 59. 57. 57. 63. 66. 62. 54. 59. 51. 49. + 52. 53. 58. 77. 99. 94. 86. 91. 89. 74. 81. 90. 77. 69. 76. 65. 76. + 157. 161. 162. 144. 127. 119. 116. 120. 126. 129. 131. 133. 137. + 137. 138. 139. 141. 143. 145. 147. 149. 148. 148. 147. 145. 143. + 141. 140. 138. 135. 133. 134. 130. 122. 115. 114. 142. 181. 210. + 217. 219. 215. 210. 214. 207. 211. 211. 208. 207. 210. 211. 209. + 208. 207. 202. 196. 193. 184. 165. 145. 97. 81. 58. 42. 37. 41. 46. + 49. 48. 50. 50. 48. 44. 40. 38. 38. 44. 57. 74. 84. 85. 89. 108. + 127. 144. 153. 163. 170. 172. 172. 173. 175. 170. 174. 176. 174. + 169. 156. 134. 114. 86. 90. 156. 197. 99. 78. 125. 109. 50. 40. 48. + 78. 75. 56. 62. 62. 72. 59. 45. 60. 44. 43. 53. 39. 81. 122. 129. + 156. 115. 90. 86. 73. 48. 84. 126. 83. 69. 127. 127. 94. 139. 140. + 144. 113. 88. 108. 137. 160. 119. 73. 40. 43. 54. 44. 40. 48. 59. + 76. 75. 67. 40. 45. 52. 67. 50. 48. 49. 52. 52. 49. 48. 50. 50. 48. + 48. 52. 59. 62. 60. 57. 60. 58. 54. 51. 56. 68. 76. 78. 75. 80. 91. + 104. 112. 114. 118. 123. 135. 139. 142. 142. 139. 138. 139. 142. + 138. 143. 149. 153. 155. 156. 157. 157. 167. 167. 169. 169. 169. + 167. 165. 163. 172. 178. 164. 125. 88. 68. 56. 46. 60. 56. 52. 51. + 50. 50. 57. 65. 55. 49. 48. 51. 53. 59. 77. 96. 92. 85. 93. 92. 75. + 80. 89. 78. 71. 70. 68. 74. 166. 156. 159. 135. 112. 113. 112. 110. + 112. 118. 122. 121. 127. 127. 128. 129. 132. 134. 136. 138. 145. + 145. 145. 145. 144. 142. 141. 140. 138. 134. 132. 131. 127. 119. + 115. 116. 154. 190. 213. 217. 217. 212. 208. 212. 206. 209. 210. + 207. 207. 209. 208. 205. 211. 203. 191. 183. 174. 152. 114. 82. 52. + 45. 37. 35. 40. 49. 56. 60. 52. 53. 53. 52. 49. 45. 42. 40. 40. 54. + 72. 80. 78. 83. 105. 129. 142. 151. 162. 170. 173. 173. 173. 174. + 165. 172. 178. 175. 166. 152. 132. 116. 125. 174. 205. 99. 88. 57. + 107. 98. 48. 43. 40. 84. 91. 63. 70. 67. 78. 58. 46. 79. 48. 47. 54. + 43. 83. 132. 121. 129. 143. 96. 66. 81. 53. 68. 97. 89. 108. 154. + 128. 76. 107. 153. 158. 105. 87. 69. 71. 164. 172. 135. 72. 16. 67. + 43. 40. 52. 56. 73. 76. 62. 42. 45. 58. 71. 50. 49. 50. 51. 51. 50. + 50. 51. 51. 50. 49. 52. 56. 59. 59. 58. 64. 60. 53. 49. 51. 61. 73. + 80. 85. 94. 108. 120. 125. 126. 127. 129. 134. 136. 139. 139. 137. + 136. 138. 139. 139. 144. 150. 155. 156. 155. 154. 154. 152. 155. + 159. 160. 162. 165. 171. 175. 186. 193. 195. 187. 176. 154. 116. 81. + 53. 46. 47. 58. 62. 56. 52. 54. 53. 49. 49. 52. 55. 63. 79. 95. 94. + 85. 93. 91. 74. 77. 89. 81. 75. 69. 74. 76. 175. 151. 154. 127. 106. + 115. 115. 107. 105. 112. 115. 112. 119. 119. 120. 121. 123. 125. + 127. 128. 135. 136. 137. 139. 140. 140. 140. 140. 139. 135. 133. + 131. 126. 119. 118. 121. 166. 197. 216. 215. 214. 210. 206. 210. + 207. 209. 210. 207. 207. 209. 206. 201. 203. 197. 188. 176. 155. + 120. 77. 45. 44. 43. 45. 50. 58. 65. 69. 70. 60. 60. 58. 57. 55. 52. + 48. 46. 38. 52. 69. 75. 73. 79. 105. 131. 138. 148. 161. 170. 173. + 173. 173. 173. 172. 179. 180. 172. 160. 151. 143. 138. 176. 193. 88. + 84. 64. 69. 111. 70. 45. 44. 39. 84. 100. 68. 66. 62. 70. 54. 52. + 91. 58. 49. 53. 45. 70. 134. 130. 107. 142. 135. 91. 49. 43. 61. 89. + 115. 144. 142. 105. 92. 89. 126. 140. 119. 121. 87. 53. 119. 159. + 173. 142. 66. 38. 41. 55. 55. 61. 77. 83. 62. 48. 49. 67. 78. 50. + 51. 51. 51. 51. 53. 53. 53. 49. 51. 53. 53. 52. 54. 58. 61. 63. 59. + 53. 48. 49. 57. 72. 83. 90. 102. 116. 124. 127. 126. 126. 125. 124. + 126. 128. 130. 131. 131. 133. 134. 138. 143. 149. 152. 152. 151. + 149. 149. 142. 145. 147. 148. 151. 158. 169. 178. 182. 187. 191. + 197. 206. 207. 188. 166. 128. 92. 58. 49. 54. 57. 58. 60. 52. 50. + 49. 52. 57. 67. 82. 95. 98. 85. 88. 88. 71. 75. 89. 84. 78. 71. 78. + 84. 179. 147. 148. 122. 113. 122. 123. 114. 108. 112. 114. 110. 113. + 113. 113. 113. 114. 115. 116. 117. 122. 123. 126. 129. 131. 133. + 134. 135. 137. 134. 132. 131. 125. 119. 120. 124. 172. 201. 216. + 213. 212. 208. 204. 208. 208. 210. 210. 208. 209. 209. 204. 197. + 193. 192. 186. 168. 136. 97. 63. 45. 35. 40. 48. 59. 69. 75. 78. 78. + 72. 69. 64. 60. 56. 52. 48. 45. 42. 54. 66. 70. 66. 73. 98. 125. + 134. 145. 159. 169. 173. 172. 171. 171. 171. 175. 173. 166. 161. + 164. 170. 172. 167. 71. 59. 72. 58. 77. 141. 34. 42. 40. 39. 72. 91. + 68. 54. 55. 60. 53. 60. 96. 79. 59. 60. 53. 65. 83. 121. 127. 114. + 126. 130. 87. 69. 81. 104. 141. 155. 115. 81. 93. 96. 88. 113. 122. + 103. 84. 81. 97. 155. 134. 138. 159. 49. 44. 49. 55. 63. 77. 85. 57. + 47. 46. 68. 75. 50. 52. 52. 50. 50. 54. 55. 54. 48. 51. 53. 52. 50. + 51. 58. 64. 58. 55. 52. 50. 50. 57. 73. 88. 90. 104. 118. 124. 125. + 126. 126. 125. 130. 132. 134. 136. 137. 139. 139. 140. 138. 141. + 145. 147. 147. 145. 144. 144. 149. 150. 150. 151. 154. 162. 174. + 183. 188. 195. 198. 196. 195. 199. 202. 202. 204. 175. 132. 89. 56. + 41. 47. 59. 50. 48. 47. 48. 55. 67. 82. 93. 101. 83. 83. 84. 70. 75. + 88. 83. 77. 73. 77. 93. 178. 147. 142. 124. 124. 129. 130. 125. 119. + 118. 118. 116. 112. 112. 110. 109. 107. 107. 107. 107. 110. 111. + 114. 117. 120. 122. 123. 124. 127. 125. 126. 125. 120. 115. 116. + 122. 174. 201. 213. 210. 209. 207. 203. 207. 209. 210. 210. 209. + 210. 209. 202. 193. 192. 184. 167. 138. 100. 64. 45. 41. 44. 50. 60. + 70. 78. 83. 84. 84. 98. 91. 81. 72. 65. 58. 52. 47. 50. 57. 64. 64. + 58. 63. 85. 110. 130. 142. 157. 168. 172. 171. 170. 169. 167. 170. + 171. 171. 174. 177. 174. 168. 101. 72. 65. 87. 79. 146. 81. 57. 43. + 36. 40. 54. 78. 73. 52. 64. 49. 50. 61. 89. 99. 72. 71. 61. 74. 36. + 82. 138. 108. 100. 117. 120. 127. 122. 139. 160. 135. 93. 79. 77. + 108. 100. 112. 124. 92. 80. 117. 134. 170. 96. 89. 159. 113. 62. 36. + 56. 57. 71. 82. 49. 44. 41. 67. 73. 48. 52. 51. 48. 48. 54. 56. 53. + 50. 50. 49. 49. 50. 54. 59. 63. 57. 55. 54. 54. 52. 56. 71. 87. 92. + 106. 119. 122. 122. 125. 128. 127. 125. 125. 127. 130. 133. 134. + 135. 134. 138. 140. 143. 143. 142. 140. 140. 141. 141. 142. 144. + 147. 153. 161. 170. 176. 179. 190. 199. 199. 196. 198. 204. 208. + 196. 207. 208. 183. 140. 95. 60. 40. 45. 43. 41. 41. 49. 63. 79. 88. + 101. 79. 79. 83. 73. 76. 85. 78. 69. 71. 72. 100. 172. 148. 138. + 129. 133. 132. 132. 134. 131. 125. 123. 125. 119. 117. 114. 111. + 108. 106. 105. 104. 102. 103. 104. 106. 108. 109. 109. 109. 112. + 112. 115. 115. 111. 106. 108. 114. 171. 197. 210. 207. 208. 206. + 203. 206. 208. 209. 209. 208. 209. 208. 199. 188. 184. 158. 123. 89. + 61. 42. 39. 45. 63. 68. 75. 81. 85. 86. 85. 85. 127. 118. 104. 91. + 81. 72. 63. 58. 57. 60. 63. 60. 52. 54. 74. 96. 128. 140. 156. 167. + 171. 170. 169. 168. 174. 177. 180. 184. 186. 176. 151. 128. 92. 78. + 53. 111. 118. 127. 78. 31. 44. 35. 41. 42. 71. 82. 59. 82. 37. 41. + 53. 74. 106. 76. 73. 60. 82. 39. 49. 117. 131. 116. 74. 69. 89. 92. + 131. 143. 87. 71. 103. 96. 88. 112. 103. 117. 118. 94. 123. 155. + 161. 114. 82. 81. 156. 81. 41. 57. 54. 68. 82. 48. 46. 45. 74. 79. + 47. 51. 50. 46. 47. 53. 55. 52. 53. 49. 45. 46. 52. 58. 61. 61. 60. + 58. 58. 58. 53. 53. 66. 83. 94. 109. 120. 120. 119. 123. 126. 126. + 124. 125. 127. 130. 134. 137. 138. 137. 138. 140. 141. 141. 139. + 138. 138. 139. 140. 142. 147. 154. 163. 171. 177. 180. 191. 193. + 194. 196. 199. 202. 201. 197. 205. 204. 203. 205. 205. 182. 127. 76. + 40. 39. 36. 35. 43. 59. 75. 84. 100. 76. 76. 83. 75. 78. 84. 73. 63. + 69. 67. 104. 167. 149. 136. 134. 137. 131. 132. 139. 139. 130. 127. + 132. 127. 124. 121. 117. 112. 109. 107. 106. 98. 99. 100. 100. 100. + 100. 99. 99. 100. 102. 105. 107. 103. 98. 100. 107. 169. 195. 207. + 205. 207. 206. 203. 206. 206. 208. 207. 206. 208. 206. 196. 185. + 165. 127. 81. 52. 42. 46. 57. 69. 63. 68. 74. 80. 82. 83. 84. 85. + 129. 128. 124. 115. 101. 86. 74. 67. 66. 67. 61. 55. 54. 52. 67. 96. + 118. 136. 156. 165. 167. 170. 172. 171. 168. 166. 186. 193. 174. + 161. 147. 119. 105. 59. 125. 116. 178. 69. 36. 45. 29. 44. 48. 38. + 42. 68. 93. 103. 28. 44. 50. 57. 116. 98. 77. 81. 91. 36. 36. 65. + 111. 142. 115. 99. 93. 75. 109. 125. 69. 94. 108. 100. 97. 110. 115. + 122. 110. 106. 125. 120. 156. 105. 75. 74. 82. 144. 61. 45. 55. 74. + 68. 49. 48. 38. 75. 68. 49. 48. 48. 49. 46. 45. 52. 62. 59. 51. 51. + 47. 50. 58. 55. 59. 61. 68. 64. 56. 54. 51. 58. 75. 94. 109. 115. + 117. 124. 123. 120. 126. 124. 128. 132. 134. 133. 133. 135. 137. + 136. 138. 141. 141. 141. 140. 141. 143. 142. 146. 152. 158. 164. + 171. 179. 184. 192. 192. 193. 195. 196. 197. 199. 199. 204. 203. + 200. 201. 208. 211. 198. 181. 104. 49. 43. 40. 42. 64. 69. 81. 106. + 67. 73. 86. 66. 70. 84. 65. 76. 64. 59. 128. 156. 157. 143. 139. + 139. 140. 140. 140. 139. 136. 134. 133. 131. 130. 128. 124. 120. + 116. 112. 110. 107. 104. 100. 97. 95. 94. 91. 89. 97. 100. 115. 114. + 108. 91. 72. 90. 157. 192. 209. 204. 204. 207. 207. 209. 201. 210. + 212. 205. 204. 204. 190. 169. 137. 83. 40. 43. 62. 69. 72. 78. 73. + 76. 81. 85. 88. 87. 86. 85. 138. 137. 134. 128. 117. 104. 91. 83. + 76. 76. 67. 58. 54. 51. 66. 96. 119. 137. 157. 165. 167. 170. 171. + 171. 173. 165. 174. 179. 166. 159. 148. 125. 102. 97. 117. 133. 157. + 59. 39. 41. 43. 44. 38. 37. 56. 85. 94. 85. 34. 25. 40. 78. 129. 90. + 76. 101. 80. 42. 42. 49. 71. 106. 115. 127. 108. 108. 118. 102. 71. + 83. 93. 113. 110. 99. 96. 124. 132. 126. 131. 118. 128. 142. 89. 42. + 99. 132. 107. 50. 51. 69. 67. 46. 43. 37. 74. 68. 53. 52. 53. 53. + 49. 47. 52. 61. 61. 54. 52. 48. 49. 55. 53. 56. 63. 70. 66. 58. 55. + 51. 59. 79. 91. 108. 114. 114. 118. 118. 119. 128. 128. 127. 127. + 129. 133. 136. 138. 138. 137. 139. 140. 140. 139. 139. 141. 143. + 144. 147. 153. 159. 165. 171. 178. 183. 189. 190. 191. 192. 194. + 195. 196. 197. 199. 202. 203. 203. 207. 212. 209. 202. 197. 126. 76. + 41. 36. 57. 65. 85. 105. 68. 72. 84. 66. 71. 85. 68. 76. 63. 64. + 135. 154. 147. 137. 141. 141. 141. 142. 141. 140. 138. 136. 135. + 136. 135. 133. 130. 126. 122. 119. 117. 112. 109. 105. 102. 100. 96. + 92. 89. 100. 105. 123. 121. 112. 91. 71. 91. 161. 194. 210. 205. + 205. 208. 208. 210. 210. 211. 209. 204. 198. 183. 154. 128. 84. 60. + 48. 60. 75. 75. 73. 75. 77. 81. 87. 89. 89. 87. 86. 86. 139. 139. + 139. 138. 135. 125. 112. 102. 90. 88. 75. 61. 53. 48. 64. 95. 121. + 139. 158. 166. 168. 170. 171. 171. 176. 166. 169. 172. 163. 156. + 145. 127. 118. 154. 119. 141. 109. 31. 35. 44. 46. 41. 33. 40. 72. + 107. 115. 104. 57. 40. 58. 98. 124. 82. 73. 100. 79. 44. 51. 70. 75. + 75. 75. 93. 120. 124. 108. 65. 73. 76. 78. 110. 129. 107. 102. 137. + 147. 131. 129. 116. 90. 129. 120. 52. 72. 104. 136. 80. 52. 64. 69. + 48. 44. 43. 79. 73. 55. 54. 54. 54. 51. 47. 50. 57. 67. 62. 56. 53. + 53. 54. 57. 57. 64. 72. 70. 62. 57. 50. 59. 82. 90. 109. 115. 112. + 115. 118. 121. 131. 129. 125. 122. 125. 133. 139. 141. 140. 140. + 140. 139. 138. 136. 137. 141. 143. 147. 150. 155. 160. 165. 171. + 178. 182. 186. 186. 187. 189. 191. 192. 194. 194. 196. 202. 206. + 204. 203. 208. 214. 217. 223. 202. 152. 78. 46. 54. 54. 64. 99. 66. + 68. 78. 64. 70. 83. 69. 72. 56. 65. 143. 154. 139. 135. 147. 144. + 144. 144. 144. 142. 141. 139. 138. 139. 138. 137. 135. 132. 129. + 126. 125. 120. 117. 114. 110. 107. 102. 96. 92. 104. 112. 132. 129. + 115. 91. 74. 98. 169. 198. 211. 206. 208. 210. 209. 212. 215. 207. + 203. 202. 187. 151. 106. 77. 40. 48. 64. 79. 84. 80. 77. 78. 83. 89. + 95. 94. 90. 85. 85. 87. 133. 133. 137. 142. 145. 139. 127. 116. 101. + 98. 81. 63. 51. 45. 62. 94. 122. 140. 159. 167. 169. 170. 172. 171. + 173. 170. 174. 176. 168. 154. 141. 130. 165. 175. 106. 113. 72. 36. + 42. 45. 37. 38. 36. 40. 62. 94. 112. 114. 112. 114. 119. 114. 100. + 74. 66. 68. 66. 41. 68. 110. 98. 60. 62. 97. 106. 98. 82. 42. 74. + 79. 78. 93. 123. 119. 124. 150. 145. 126. 135. 132. 74. 58. 132. + 115. 37. 71. 120. 129. 54. 54. 66. 48. 44. 48. 80. 73. 53. 51. 52. + 53. 51. 47. 49. 54. 65. 65. 54. 54. 53. 51. 60. 59. 64. 74. 75. 69. + 59. 48. 57. 83. 91. 110. 116. 114. 120. 124. 124. 129. 124. 124. + 125. 129. 134. 139. 141. 142. 142. 141. 139. 136. 135. 137. 141. + 145. 150. 153. 157. 161. 165. 170. 176. 180. 183. 184. 185. 187. + 189. 191. 192. 193. 196. 201. 204. 202. 199. 201. 208. 214. 199. + 220. 208. 156. 100. 52. 36. 61. 89. 62. 62. 69. 61. 69. 80. 69. 67. + 46. 62. 150. 156. 137. 138. 154. 147. 147. 147. 146. 144. 143. 142. + 141. 139. 138. 137. 136. 134. 132. 129. 128. 125. 123. 120. 118. + 115. 110. 103. 99. 109. 116. 135. 131. 115. 92. 82. 115. 179. 203. + 212. 208. 210. 212. 210. 213. 212. 201. 199. 199. 173. 118. 69. 47. + 43. 62. 82. 87. 83. 81. 83. 85. 89. 96. 100. 97. 89. 84. 85. 88. + 131. 132. 138. 146. 151. 147. 135. 125. 111. 107. 87. 66. 50. 42. + 60. 93. 122. 140. 159. 168. 169. 171. 173. 173. 171. 175. 179. 178. + 170. 153. 145. 149. 211. 153. 92. 83. 65. 70. 57. 42. 40. 42. 40. + 39. 47. 62. 70. 69. 89. 108. 107. 86. 64. 65. 65. 64. 82. 82. 102. + 109. 65. 33. 78. 140. 75. 55. 70. 54. 72. 80. 91. 88. 95. 110. 125. + 143. 136. 133. 153. 151. 96. 19. 93. 156. 89. 55. 97. 153. 66. 42. + 55. 43. 41. 47. 74. 67. 53. 50. 51. 53. 53. 50. 52. 56. 59. 64. 48. + 52. 52. 47. 64. 60. 63. 76. 82. 78. 64. 46. 53. 80. 90. 110. 116. + 115. 124. 129. 124. 122. 118. 125. 133. 136. 136. 136. 139. 143. + 143. 142. 139. 136. 135. 137. 143. 147. 153. 155. 159. 162. 165. + 169. 174. 177. 181. 182. 183. 185. 187. 189. 191. 192. 196. 197. + 199. 201. 202. 202. 204. 207. 211. 211. 210. 215. 174. 83. 43. 68. + 80. 60. 58. 64. 62. 70. 78. 70. 68. 41. 63. 155. 157. 137. 140. 152. + 149. 149. 148. 146. 145. 144. 143. 143. 139. 139. 139. 138. 136. + 134. 132. 131. 127. 126. 125. 124. 122. 118. 113. 109. 113. 117. + 134. 130. 114. 96. 97. 140. 188. 207. 213. 209. 212. 213. 210. 214. + 209. 200. 198. 192. 152. 90. 50. 41. 66. 82. 93. 89. 82. 83. 87. 90. + 96. 101. 103. 97. 88. 83. 86. 91. 130. 133. 141. 149. 154. 151. 142. + 134. 124. 118. 97. 72. 53. 42. 59. 93. 121. 140. 159. 168. 171. 173. + 175. 175. 172. 178. 177. 172. 167. 152. 152. 171. 219. 133. 119. + 100. 52. 62. 49. 44. 54. 51. 48. 51. 61. 63. 50. 33. 54. 69. 60. 58. + 52. 60. 58. 74. 83. 96. 91. 68. 31. 37. 101. 142. 59. 37. 72. 79. + 67. 76. 97. 99. 88. 99. 107. 127. 134. 140. 154. 140. 128. 57. 47. + 141. 180. 72. 94. 129. 102. 45. 50. 43. 44. 50. 71. 68. 57. 53. 52. + 55. 55. 54. 56. 60. 61. 70. 50. 58. 58. 50. 74. 68. 62. 79. 91. 90. + 71. 46. 49. 77. 86. 109. 117. 114. 122. 126. 120. 116. 119. 129. + 140. 142. 137. 134. 138. 143. 142. 142. 140. 138. 137. 140. 145. + 149. 155. 157. 160. 162. 164. 167. 171. 174. 178. 179. 181. 183. + 185. 188. 189. 190. 194. 192. 195. 202. 206. 206. 206. 208. 215. + 217. 206. 218. 217. 165. 98. 41. 72. 59. 56. 60. 64. 73. 77. 71. 70. + 44. 70. 161. 154. 135. 140. 146. 150. 149. 147. 145. 144. 144. 143. + 143. 143. 143. 142. 141. 140. 138. 136. 135. 130. 128. 127. 127. + 126. 124. 120. 117. 118. 118. 132. 129. 116. 104. 113. 163. 197. + 211. 213. 209. 213. 213. 210. 214. 208. 200. 195. 178. 129. 71. 46. + 52. 80. 89. 95. 92. 87. 87. 90. 93. 104. 104. 102. 96. 88. 86. 90. + 95. 115. 122. 134. 144. 151. 151. 148. 145. 138. 133. 110. 82. 58. + 45. 60. 93. 120. 139. 159. 168. 171. 175. 177. 177. 174. 180. 174. + 170. 169. 153. 150. 172. 203. 116. 132. 131. 33. 37. 40. 48. 56. 53. + 52. 60. 73. 76. 61. 43. 76. 86. 58. 63. 72. 75. 48. 60. 45. 50. 44. + 52. 47. 57. 105. 120. 76. 47. 63. 81. 64. 74. 84. 102. 100. 95. 96. + 125. 138. 135. 138. 118. 135. 111. 59. 116. 177. 112. 95. 82. 151. + 59. 49. 45. 48. 54. 72. 73. 62. 56. 53. 54. 54. 53. 55. 59. 64. 76. + 53. 62. 61. 51. 79. 72. 62. 83. 101. 102. 80. 48. 46. 74. 84. 113. + 123. 115. 116. 120. 119. 121. 127. 134. 140. 141. 138. 136. 138. + 142. 141. 141. 141. 140. 140. 143. 148. 151. 156. 158. 160. 161. + 162. 164. 168. 171. 175. 176. 177. 180. 182. 185. 187. 187. 192. + 190. 194. 201. 205. 204. 207. 212. 202. 222. 211. 210. 222. 221. + 168. 64. 61. 54. 51. 55. 63. 71. 73. 67. 65. 47. 81. 166. 150. 133. + 143. 147. 149. 148. 146. 144. 143. 142. 143. 143. 145. 144. 144. + 143. 141. 139. 137. 136. 133. 131. 129. 128. 127. 126. 123. 121. + 123. 120. 133. 131. 123. 114. 126. 179. 203. 213. 212. 209. 214. + 213. 209. 213. 206. 197. 184. 157. 108. 63. 54. 70. 87. 90. 93. 94. + 91. 90. 95. 102. 111. 108. 101. 94. 90. 91. 96. 100. 96. 106. 121. + 136. 145. 150. 152. 153. 149. 143. 120. 89. 63. 47. 61. 94. 119. + 138. 158. 168. 172. 176. 178. 179. 174. 181. 174. 173. 175. 154. + 140. 157. 194. 92. 97. 134. 27. 44. 49. 44. 46. 47. 48. 53. 60. 66. + 64. 59. 45. 67. 35. 45. 77. 97. 57. 56. 49. 42. 45. 79. 63. 29. 60. + 83. 103. 63. 44. 66. 63. 77. 66. 92. 104. 91. 94. 133. 144. 128. + 128. 115. 123. 132. 104. 114. 103. 144. 89. 49. 181. 66. 46. 42. 46. + 51. 68. 73. 64. 57. 52. 51. 51. 50. 52. 55. 59. 73. 47. 58. 56. 44. + 74. 66. 63. 86. 107. 110. 86. 50. 45. 72. 84. 119. 131. 118. 112. + 115. 120. 129. 136. 137. 138. 139. 138. 139. 139. 140. 140. 141. + 142. 142. 142. 145. 149. 153. 156. 158. 160. 161. 161. 163. 166. + 169. 172. 173. 175. 177. 180. 182. 184. 185. 192. 191. 194. 200. + 200. 198. 203. 212. 211. 210. 203. 221. 220. 213. 208. 156. 52. 48. + 45. 49. 59. 67. 67. 62. 56. 46. 87. 170. 147. 132. 148. 152. 149. + 147. 145. 143. 142. 141. 142. 142. 144. 144. 143. 142. 140. 137. + 135. 134. 136. 133. 130. 128. 127. 126. 124. 122. 127. 122. 135. + 135. 128. 120. 133. 186. 206. 214. 212. 209. 214. 213. 209. 213. + 202. 191. 172. 141. 96. 62. 64. 84. 94. 92. 92. 94. 91. 90. 100. + 114. 116. 110. 101. 94. 91. 94. 100. 105. 60. 83. 111. 130. 142. + 152. 159. 162. 158. 145. 127. 102. 64. 40. 58. 93. 122. 145. 160. + 167. 177. 177. 173. 176. 177. 177. 179. 177. 167. 155. 154. 161. + 147. 115. 66. 77. 32. 31. 52. 41. 46. 37. 48. 64. 63. 57. 56. 52. + 51. 42. 38. 50. 101. 98. 53. 78. 54. 41. 40. 74. 83. 40. 31. 74. 99. + 94. 61. 48. 77. 71. 61. 83. 96. 108. 88. 129. 145. 128. 114. 143. + 135. 136. 109. 125. 63. 133. 163. 43. 160. 125. 37. 30. 45. 43. 80. + 61. 50. 67. 45. 54. 48. 52. 49. 50. 61. 69. 53. 50. 49. 41. 59. 75. + 59. 94. 114. 115. 99. 61. 43. 62. 85. 112. 115. 104. 114. 132. 135. + 131. 133. 134. 137. 139. 140. 139. 138. 136. 140. 139. 138. 139. + 140. 143. 146. 148. 152. 155. 158. 160. 161. 163. 165. 167. 169. + 171. 174. 176. 178. 180. 183. 186. 190. 191. 193. 196. 198. 201. + 203. 204. 207. 209. 213. 216. 217. 216. 214. 213. 123. 50. 42. 55. + 50. 75. 47. 67. 49. 45. 103. 161. 140. 131. 158. 141. 145. 144. 144. + 144. 144. 144. 143. 143. 144. 144. 143. 143. 141. 140. 138. 137. + 131. 137. 136. 129. 124. 126. 126. 123. 129. 133. 140. 138. 126. + 127. 158. 195. 210. 213. 213. 211. 212. 214. 213. 209. 201. 186. + 153. 108. 76. 71. 83. 95. 92. 92. 91. 92. 95. 101. 107. 111. 110. + 103. 95. 92. 93. 97. 100. 101. 48. 69. 96. 119. 137. 153. 161. 163. + 164. 152. 136. 111. 71. 44. 59. 93. 122. 145. 159. 167. 177. 177. + 173. 176. 177. 176. 178. 177. 168. 156. 152. 155. 179. 109. 80. 48. + 44. 46. 43. 41. 48. 41. 56. 73. 63. 50. 53. 60. 48. 48. 43. 56. 108. + 97. 48. 77. 56. 32. 38. 77. 99. 65. 37. 67. 89. 84. 78. 68. 67. 80. + 85. 71. 77. 103. 93. 114. 111. 111. 119. 143. 134. 170. 133. 112. + 34. 79. 152. 92. 146. 146. 42. 33. 42. 37. 73. 60. 53. 69. 45. 53. + 47. 52. 50. 51. 65. 72. 54. 52. 52. 42. 57. 69. 64. 97. 116. 117. + 103. 63. 42. 59. 80. 108. 115. 108. 119. 134. 134. 130. 133. 134. + 136. 138. 139. 139. 139. 138. 141. 140. 139. 140. 141. 144. 147. + 149. 151. 154. 158. 160. 161. 162. 164. 166. 168. 171. 174. 176. + 177. 179. 183. 185. 190. 191. 193. 195. 198. 201. 203. 204. 205. + 207. 210. 214. 216. 217. 217. 217. 171. 103. 36. 48. 46. 66. 46. 65. + 49. 46. 112. 160. 137. 134. 152. 143. 147. 147. 147. 146. 146. 146. + 145. 145. 143. 143. 142. 142. 141. 140. 138. 138. 132. 136. 135. + 130. 127. 129. 128. 123. 128. 132. 139. 139. 131. 134. 164. 198. + 214. 216. 216. 213. 213. 215. 213. 209. 200. 176. 136. 97. 76. 76. + 86. 95. 90. 90. 92. 96. 102. 107. 111. 113. 102. 98. 94. 93. 96. + 100. 102. 103. 35. 51. 76. 102. 130. 153. 165. 166. 168. 158. 144. + 119. 76. 45. 56. 87. 122. 144. 159. 167. 177. 177. 173. 177. 178. + 176. 177. 176. 170. 158. 150. 147. 159. 132. 96. 62. 49. 40. 35. 43. + 47. 46. 65. 78. 59. 41. 48. 63. 45. 54. 45. 63. 118. 95. 42. 74. 62. + 36. 41. 55. 84. 84. 45. 48. 86. 64. 83. 96. 67. 86. 105. 77. 60. 92. + 96. 112. 97. 111. 123. 117. 134. 184. 152. 112. 40. 29. 103. 120. + 131. 176. 47. 37. 39. 33. 68. 63. 56. 72. 46. 52. 45. 51. 50. 53. + 68. 73. 54. 54. 55. 44. 54. 60. 72. 102. 118. 118. 105. 66. 42. 56. + 76. 104. 116. 114. 126. 136. 133. 129. 133. 134. 135. 136. 138. 139. + 140. 140. 141. 141. 140. 141. 143. 145. 148. 149. 151. 153. 157. + 159. 160. 161. 163. 165. 168. 170. 173. 176. 177. 179. 182. 185. + 189. 190. 192. 195. 198. 200. 203. 204. 203. 205. 208. 211. 215. + 218. 220. 221. 215. 165. 48. 40. 46. 60. 44. 59. 47. 46. 126. 158. + 133. 138. 144. 148. 147. 147. 147. 146. 146. 145. 145. 145. 142. + 142. 141. 141. 140. 139. 139. 138. 135. 136. 134. 131. 130. 131. + 128. 123. 125. 130. 140. 145. 144. 150. 175. 203. 215. 217. 215. + 212. 213. 215. 212. 207. 198. 161. 114. 84. 78. 84. 91. 93. 92. 92. + 95. 102. 109. 112. 110. 108. 93. 92. 93. 95. 100. 103. 104. 104. 29. + 40. 59. 88. 124. 155. 168. 168. 169. 161. 149. 123. 77. 41. 49. 78. + 121. 144. 159. 167. 177. 178. 174. 177. 178. 177. 176. 176. 172. + 161. 148. 139. 119. 170. 80. 80. 36. 34. 45. 44. 44. 52. 69. 71. 50. + 40. 48. 54. 44. 56. 41. 68. 127. 94. 39. 68. 68. 49. 45. 25. 51. 91. + 66. 56. 93. 52. 67. 107. 79. 86. 104. 103. 81. 87. 84. 106. 94. 123. + 134. 105. 140. 161. 140. 96. 63. 27. 58. 139. 132. 200. 49. 38. 38. + 35. 70. 66. 61. 75. 47. 52. 45. 51. 51. 54. 67. 70. 51. 52. 57. 47. + 53. 56. 82. 106. 115. 115. 104. 68. 43. 54. 79. 104. 116. 118. 129. + 135. 131. 128. 134. 134. 134. 135. 137. 139. 141. 142. 141. 141. + 141. 142. 144. 146. 148. 149. 149. 152. 156. 158. 159. 160. 162. + 164. 167. 170. 173. 175. 176. 178. 181. 184. 187. 189. 191. 194. + 197. 200. 202. 203. 205. 205. 207. 209. 213. 217. 220. 223. 227. + 199. 97. 38. 47. 57. 39. 51. 41. 48. 138. 156. 130. 144. 141. 155. + 146. 145. 145. 144. 144. 143. 142. 142. 141. 141. 140. 139. 139. + 138. 139. 139. 137. 135. 133. 130. 130. 129. 125. 121. 123. 131. + 145. 157. 162. 170. 188. 207. 214. 215. 213. 211. 212. 214. 210. + 203. 189. 144. 96. 78. 85. 93. 93. 90. 97. 97. 101. 108. 112. 111. + 104. 97. 87. 89. 94. 99. 102. 104. 104. 103. 31. 36. 51. 79. 119. + 154. 170. 170. 170. 163. 151. 124. 76. 37. 44. 73. 120. 143. 159. + 167. 177. 178. 174. 178. 178. 178. 177. 176. 172. 163. 147. 135. + 110. 164. 74. 53. 31. 48. 54. 42. 46. 58. 69. 59. 43. 48. 54. 44. + 46. 52. 36. 74. 132. 93. 41. 60. 76. 51. 43. 26. 40. 77. 81. 85. 94. + 66. 54. 89. 79. 90. 95. 116. 115. 90. 68. 90. 80. 119. 150. 133. + 145. 141. 127. 57. 56. 56. 52. 167. 155. 206. 48. 38. 38. 38. 73. + 62. 64. 78. 49. 53. 45. 51. 51. 54. 62. 65. 46. 49. 56. 48. 55. 59. + 91. 108. 111. 109. 103. 69. 45. 54. 86. 106. 116. 120. 129. 132. + 128. 130. 135. 135. 135. 135. 137. 139. 140. 141. 140. 141. 142. + 143. 144. 146. 148. 149. 148. 151. 155. 157. 158. 159. 161. 163. + 166. 169. 172. 174. 175. 177. 180. 183. 186. 187. 190. 193. 196. + 199. 202. 203. 207. 207. 207. 208. 211. 215. 218. 220. 222. 210. + 162. 48. 40. 51. 34. 47. 34. 55. 144. 154. 131. 147. 143. 158. 146. + 146. 145. 144. 143. 143. 142. 141. 142. 141. 139. 138. 137. 137. + 138. 138. 138. 134. 131. 129. 127. 124. 121. 120. 127. 140. 159. + 174. 182. 188. 200. 211. 214. 214. 213. 212. 214. 215. 208. 199. + 174. 128. 87. 81. 94. 98. 92. 88. 98. 100. 105. 110. 112. 108. 98. + 91. 87. 91. 97. 101. 103. 103. 102. 101. 35. 37. 47. 73. 113. 151. + 168. 170. 173. 165. 154. 125. 75. 36. 43. 73. 120. 143. 158. 167. + 177. 178. 175. 178. 177. 180. 180. 177. 172. 163. 149. 135. 104. + 120. 121. 38. 49. 55. 39. 42. 54. 60. 64. 52. 43. 54. 58. 43. 47. + 47. 38. 90. 134. 87. 43. 49. 87. 50. 36. 51. 49. 44. 63. 82. 77. 83. + 55. 66. 66. 99. 92. 107. 110. 88. 70. 91. 76. 108. 150. 154. 134. + 151. 144. 54. 42. 73. 54. 157. 181. 187. 46. 39. 37. 38. 77. 56. 67. + 80. 52. 55. 46. 51. 50. 53. 60. 63. 43. 46. 54. 49. 60. 67. 95. 108. + 107. 107. 105. 74. 47. 54. 91. 107. 116. 122. 131. 129. 126. 131. + 135. 135. 136. 137. 138. 138. 139. 139. 139. 140. 141. 143. 144. + 146. 147. 148. 147. 150. 153. 156. 156. 158. 160. 162. 165. 168. + 171. 173. 174. 177. 180. 182. 185. 186. 189. 192. 196. 199. 202. + 203. 208. 208. 208. 209. 211. 213. 216. 218. 222. 216. 208. 86. 33. + 41. 31. 45. 30. 66. 145. 154. 134. 146. 147. 156. 149. 149. 148. + 147. 146. 144. 144. 143. 143. 141. 139. 137. 135. 135. 136. 136. + 136. 132. 130. 128. 124. 120. 122. 127. 143. 158. 177. 191. 196. + 200. 207. 213. 216. 216. 216. 215. 216. 214. 203. 191. 153. 114. 85. + 88. 99. 97. 92. 93. 97. 102. 108. 111. 110. 104. 96. 91. 91. 95. 99. + 102. 102. 101. 101. 101. 37. 37. 44. 67. 107. 146. 165. 169. 174. + 166. 153. 123. 72. 34. 43. 75. 119. 143. 158. 167. 177. 178. 175. + 179. 176. 181. 182. 177. 171. 163. 150. 138. 122. 103. 138. 45. 59. + 47. 28. 50. 62. 53. 52. 51. 45. 49. 54. 49. 46. 45. 50. 112. 135. + 78. 44. 38. 83. 56. 33. 65. 57. 32. 57. 53. 54. 70. 52. 69. 59. 99. + 92. 100. 97. 92. 77. 95. 79. 105. 140. 146. 122. 160. 148. 90. 48. + 59. 47. 132. 189. 146. 39. 41. 36. 38. 85. 56. 68. 82. 54. 57. 48. + 52. 50. 52. 62. 65. 44. 45. 52. 49. 65. 75. 95. 107. 107. 109. 111. + 81. 51. 53. 90. 105. 115. 125. 134. 130. 126. 133. 135. 136. 138. + 138. 139. 138. 137. 136. 138. 139. 140. 142. 144. 145. 146. 146. + 146. 149. 153. 155. 156. 157. 159. 161. 165. 167. 171. 173. 174. + 176. 179. 182. 184. 185. 188. 191. 195. 199. 201. 203. 207. 207. + 208. 209. 211. 214. 216. 217. 222. 221. 218. 151. 40. 38. 35. 39. + 29. 81. 144. 156. 137. 141. 151. 149. 149. 149. 148. 147. 145. 144. + 143. 143. 144. 142. 139. 136. 134. 134. 134. 134. 132. 130. 129. + 128. 122. 119. 126. 138. 166. 181. 196. 203. 202. 204. 209. 215. + 216. 217. 216. 215. 214. 208. 193. 177. 131. 101. 84. 92. 98. 91. + 92. 102. 101. 107. 113. 113. 106. 98. 93. 92. 94. 97. 101. 102. 101. + 101. 103. 104. 36. 36. 41. 63. 102. 141. 163. 168. 172. 164. 150. + 119. 68. 31. 41. 75. 119. 142. 158. 167. 177. 179. 175. 179. 176. + 182. 184. 178. 170. 163. 152. 140. 173. 124. 91. 41. 51. 44. 42. 58. + 65. 43. 41. 52. 46. 39. 46. 56. 44. 44. 62. 129. 135. 71. 43. 32. + 66. 64. 34. 61. 59. 49. 81. 42. 38. 42. 44. 86. 62. 92. 92. 104. + 109. 104. 74. 79. 70. 105. 137. 140. 122. 154. 121. 114. 56. 38. 49. + 137. 184. 111. 32. 41. 36. 39. 94. 61. 68. 82. 55. 58. 49. 52. 49. + 51. 65. 68. 46. 46. 51. 49. 68. 81. 94. 106. 108. 113. 117. 86. 53. + 52. 87. 102. 114. 127. 138. 132. 126. 134. 135. 137. 139. 140. 139. + 138. 135. 134. 137. 138. 140. 142. 143. 145. 145. 145. 146. 149. + 152. 154. 155. 156. 159. 160. 164. 167. 170. 172. 174. 176. 179. + 181. 183. 185. 187. 191. 195. 198. 201. 203. 204. 205. 207. 210. + 212. 215. 216. 217. 218. 223. 210. 206. 55. 41. 39. 32. 30. 91. 143. + 157. 139. 137. 153. 144. 147. 147. 146. 145. 143. 142. 141. 140. + 145. 143. 139. 136. 133. 132. 133. 133. 129. 128. 128. 128. 122. + 120. 131. 147. 184. 197. 208. 208. 203. 203. 209. 215. 215. 215. + 214. 212. 209. 201. 182. 164. 117. 93. 83. 93. 96. 87. 93. 111. 108. + 115. 119. 115. 104. 93. 89. 89. 95. 98. 101. 101. 100. 101. 104. + 108. 33. 34. 38. 56. 96. 139. 161. 163. 172. 167. 151. 123. 79. 35. + 37. 75. 115. 143. 161. 167. 176. 179. 177. 178. 176. 180. 181. 177. + 171. 162. 147. 134. 165. 117. 71. 47. 54. 31. 57. 62. 51. 46. 45. + 41. 40. 51. 53. 39. 44. 41. 99. 121. 139. 61. 47. 41. 45. 59. 43. + 72. 58. 48. 54. 55. 49. 48. 45. 54. 72. 78. 85. 101. 118. 107. 59. + 78. 59. 96. 150. 135. 135. 141. 128. 144. 111. 71. 65. 149. 156. 81. + 138. 25. 38. 59. 92. 63. 72. 66. 57. 51. 48. 50. 52. 53. 54. 55. 56. + 55. 51. 53. 68. 84. 103. 117. 120. 122. 120. 84. 52. 56. 89. 105. + 121. 128. 131. 134. 135. 134. 136. 136. 137. 138. 138. 138. 137. + 137. 135. 136. 138. 140. 142. 144. 146. 147. 147. 148. 150. 152. + 154. 157. 158. 159. 161. 163. 165. 168. 172. 175. 178. 179. 182. + 184. 188. 191. 193. 196. 200. 203. 205. 207. 209. 210. 210. 211. + 213. 215. 216. 220. 224. 217. 130. 36. 30. 32. 29. 108. 133. 151. + 144. 148. 144. 150. 147. 147. 146. 146. 145. 144. 143. 143. 140. + 139. 137. 135. 133. 132. 132. 132. 125. 126. 128. 132. 129. 118. + 136. 176. 202. 210. 215. 210. 205. 206. 210. 213. 213. 216. 217. + 215. 211. 197. 169. 143. 99. 95. 91. 88. 90. 95. 101. 106. 114. 116. + 115. 109. 99. 91. 89. 91. 99. 104. 105. 101. 101. 105. 104. 99. 34. + 33. 35. 51. 91. 136. 161. 165. 174. 169. 153. 125. 80. 35. 35. 72. + 115. 143. 161. 167. 176. 179. 176. 178. 175. 180. 181. 177. 171. + 162. 148. 135. 148. 94. 46. 38. 63. 48. 60. 50. 49. 39. 42. 49. 46. + 44. 43. 34. 25. 69. 134. 129. 115. 62. 51. 39. 45. 57. 50. 69. 55. + 52. 45. 44. 50. 57. 52. 52. 64. 69. 73. 88. 121. 106. 55. 60. 63. + 115. 150. 128. 139. 152. 97. 91. 139. 100. 117. 180. 144. 139. 173. + 57. 40. 38. 76. 55. 66. 65. 63. 61. 58. 53. 48. 44. 50. 51. 53. 55. + 56. 63. 82. 100. 114. 122. 121. 125. 120. 82. 55. 67. 90. 105. 121. + 128. 130. 133. 134. 133. 136. 137. 137. 138. 138. 138. 137. 136. + 136. 137. 138. 140. 142. 143. 145. 146. 147. 147. 149. 152. 154. + 156. 158. 159. 161. 162. 165. 168. 171. 174. 177. 178. 181. 184. + 188. 191. 193. 196. 199. 202. 204. 206. 209. 210. 210. 211. 213. + 215. 218. 227. 224. 216. 164. 41. 32. 29. 36. 115. 136. 148. 141. + 149. 147. 148. 147. 147. 146. 145. 144. 144. 143. 143. 140. 139. + 137. 135. 134. 133. 132. 131. 129. 128. 125. 127. 125. 119. 141. + 184. 205. 213. 217. 211. 206. 208. 212. 214. 219. 219. 216. 212. + 206. 188. 155. 125. 99. 96. 91. 89. 90. 95. 101. 106. 112. 113. 112. + 105. 97. 91. 91. 94. 101. 105. 105. 101. 100. 102. 100. 95. 33. 32. + 32. 47. 86. 132. 161. 167. 176. 171. 155. 128. 83. 36. 34. 69. 114. + 143. 161. 167. 176. 179. 176. 177. 177. 181. 182. 178. 173. 164. + 150. 138. 138. 90. 45. 45. 68. 53. 55. 39. 52. 36. 38. 50. 46. 40. + 40. 39. 76. 98. 114. 103. 87. 68. 50. 31. 45. 55. 62. 66. 49. 56. + 34. 36. 47. 64. 57. 46. 57. 64. 63. 73. 124. 115. 78. 66. 79. 131. + 146. 134. 148. 167. 132. 98. 138. 81. 137. 161. 115. 121. 114. 47. + 46. 44. 75. 58. 60. 58. 55. 53. 54. 57. 62. 65. 48. 49. 52. 56. 61. + 73. 95. 115. 124. 124. 120. 125. 118. 75. 54. 78. 91. 106. 121. 127. + 130. 132. 133. 133. 137. 137. 138. 138. 138. 138. 137. 136. 137. + 137. 138. 139. 141. 142. 143. 144. 146. 147. 149. 151. 153. 156. + 157. 158. 161. 162. 164. 167. 170. 173. 176. 177. 181. 184. 187. + 190. 192. 195. 199. 202. 204. 206. 208. 209. 209. 210. 212. 215. + 215. 228. 221. 216. 204. 64. 31. 30. 43. 124. 141. 145. 138. 152. + 149. 145. 146. 146. 145. 145. 144. 143. 142. 142. 140. 139. 138. + 136. 134. 133. 132. 131. 132. 129. 123. 121. 121. 120. 149. 194. + 210. 216. 218. 212. 207. 209. 214. 216. 221. 218. 213. 208. 199. + 177. 140. 109. 101. 97. 93. 90. 91. 96. 102. 106. 112. 111. 108. + 101. 94. 91. 94. 97. 103. 105. 105. 101. 99. 97. 93. 88. 31. 30. 31. + 46. 84. 131. 160. 168. 175. 171. 156. 131. 88. 40. 36. 69. 113. 142. + 161. 167. 177. 179. 175. 176. 177. 181. 182. 178. 173. 165. 152. + 140. 125. 97. 61. 59. 61. 44. 48. 43. 54. 41. 40. 43. 41. 45. 53. + 53. 113. 85. 62. 85. 82. 71. 41. 38. 44. 55. 72. 63. 41. 57. 30. 39. + 43. 67. 54. 39. 59. 70. 61. 63. 108. 114. 110. 96. 104. 129. 133. + 146. 142. 105. 126. 130. 163. 146. 195. 145. 62. 38. 39. 53. 68. 66. + 57. 40. 71. 67. 60. 53. 49. 49. 53. 56. 50. 50. 52. 57. 64. 78. 100. + 120. 126. 122. 117. 125. 114. 66. 49. 83. 94. 108. 122. 128. 129. + 132. 133. 132. 138. 138. 139. 139. 138. 138. 137. 136. 137. 137. + 138. 139. 140. 141. 142. 142. 145. 146. 148. 150. 153. 155. 157. + 158. 160. 161. 163. 166. 169. 172. 174. 175. 180. 183. 186. 189. + 191. 194. 198. 201. 203. 205. 207. 208. 208. 209. 212. 214. 211. + 220. 217. 217. 226. 111. 23. 35. 45. 128. 143. 144. 138. 156. 151. + 141. 145. 145. 145. 144. 143. 142. 142. 141. 139. 139. 138. 137. + 135. 134. 132. 131. 131. 129. 122. 120. 120. 125. 156. 201. 212. + 217. 217. 211. 207. 210. 214. 216. 216. 215. 212. 205. 189. 163. + 132. 109. 104. 100. 96. 93. 94. 98. 104. 109. 115. 112. 105. 97. 92. + 91. 96. 100. 104. 105. 104. 101. 97. 92. 87. 83. 29. 30. 33. 48. 85. + 130. 158. 166. 173. 169. 156. 134. 93. 45. 39. 69. 112. 141. 160. + 167. 177. 179. 174. 175. 173. 177. 178. 174. 169. 163. 150. 139. + 117. 98. 63. 61. 52. 40. 47. 50. 46. 47. 49. 42. 41. 60. 71. 60. 67. + 51. 50. 102. 92. 71. 39. 54. 45. 57. 74. 62. 37. 55. 34. 49. 44. 69. + 51. 37. 70. 80. 59. 55. 72. 81. 108. 120. 130. 124. 123. 147. 133. + 71. 111. 121. 132. 151. 164. 127. 96. 50. 65. 78. 59. 71. 54. 57. + 52. 57. 63. 66. 63. 57. 53. 51. 49. 48. 52. 59. 68. 82. 103. 121. + 125. 121. 118. 126. 112. 61. 47. 86. 98. 111. 124. 129. 129. 131. + 133. 132. 139. 139. 139. 139. 139. 138. 137. 136. 136. 136. 137. + 138. 139. 140. 141. 141. 144. 145. 147. 149. 152. 154. 156. 157. + 159. 160. 162. 165. 168. 170. 172. 173. 179. 182. 186. 189. 191. + 194. 197. 200. 202. 204. 207. 208. 208. 209. 211. 213. 213. 212. + 216. 219. 223. 161. 20. 35. 47. 128. 142. 143. 140. 158. 152. 139. + 145. 144. 144. 143. 142. 141. 141. 141. 139. 139. 139. 138. 137. + 134. 132. 131. 127. 129. 124. 122. 124. 130. 161. 204. 212. 215. + 214. 207. 205. 209. 214. 216. 212. 215. 214. 201. 176. 147. 126. + 116. 107. 104. 99. 96. 96. 101. 107. 111. 117. 112. 104. 95. 91. 92. + 97. 102. 105. 103. 102. 100. 95. 89. 84. 82. 29. 31. 34. 48. 83. + 127. 156. 164. 172. 168. 158. 137. 98. 49. 40. 69. 111. 141. 160. + 167. 177. 179. 174. 174. 169. 173. 173. 170. 165. 159. 148. 137. + 136. 110. 61. 60. 50. 47. 47. 44. 36. 48. 57. 49. 48. 68. 74. 55. + 41. 44. 55. 99. 90. 75. 47. 52. 49. 59. 63. 62. 41. 52. 42. 53. 48. + 72. 50. 41. 81. 87. 55. 49. 46. 48. 84. 125. 149. 127. 131. 138. + 114. 86. 104. 82. 91. 131. 131. 162. 178. 146. 140. 114. 76. 89. 60. + 61. 62. 65. 67. 66. 61. 58. 59. 61. 45. 46. 52. 63. 75. 89. 108. + 125. 124. 125. 124. 128. 112. 63. 51. 91. 102. 115. 127. 130. 130. + 132. 134. 133. 140. 140. 140. 140. 139. 138. 137. 136. 134. 135. + 136. 137. 139. 140. 141. 141. 144. 145. 146. 149. 151. 153. 155. + 156. 159. 160. 162. 164. 167. 169. 171. 172. 178. 181. 185. 188. + 190. 193. 196. 199. 201. 204. 206. 207. 207. 208. 210. 212. 218. + 212. 215. 222. 215. 194. 44. 29. 56. 129. 139. 143. 141. 157. 151. + 141. 144. 144. 143. 142. 141. 141. 140. 140. 139. 139. 140. 139. + 137. 135. 132. 131. 124. 129. 126. 124. 127. 135. 165. 206. 211. + 213. 210. 204. 203. 209. 215. 216. 215. 216. 211. 193. 160. 131. + 118. 119. 109. 106. 101. 97. 98. 102. 108. 112. 115. 109. 100. 92. + 90. 93. 99. 103. 104. 100. 98. 98. 94. 88. 85. 86. 30. 31. 32. 43. + 77. 122. 154. 164. 173. 170. 160. 140. 101. 51. 39. 66. 110. 140. + 160. 168. 177. 179. 173. 174. 171. 174. 174. 171. 167. 161. 150. + 140. 146. 119. 62. 61. 47. 49. 46. 43. 40. 46. 55. 52. 48. 60. 64. + 49. 59. 51. 51. 78. 81. 73. 50. 45. 56. 61. 46. 62. 51. 51. 47. 47. + 45. 72. 52. 47. 90. 87. 50. 50. 42. 43. 74. 121. 143. 117. 141. 122. + 135. 104. 78. 30. 36. 69. 58. 51. 58. 88. 84. 101. 134. 142. 117. + 129. 115. 106. 89. 68. 50. 42. 45. 50. 46. 48. 58. 71. 84. 97. 113. + 126. 123. 129. 127. 126. 108. 64. 57. 97. 105. 118. 129. 132. 131. + 133. 135. 134. 140. 140. 140. 140. 139. 138. 137. 136. 132. 133. + 135. 136. 138. 140. 141. 142. 143. 144. 146. 148. 150. 153. 155. + 155. 158. 159. 161. 163. 166. 168. 169. 170. 178. 181. 184. 187. + 189. 192. 196. 199. 201. 203. 205. 206. 206. 207. 210. 212. 217. + 217. 211. 221. 216. 205. 97. 26. 71. 134. 137. 143. 141. 153. 149. + 146. 143. 143. 142. 142. 141. 140. 139. 139. 139. 140. 140. 140. + 138. 135. 132. 131. 123. 130. 128. 125. 128. 138. 168. 208. 211. + 212. 208. 203. 203. 210. 217. 218. 217. 212. 201. 178. 146. 120. + 114. 120. 109. 105. 100. 97. 97. 101. 107. 111. 108. 102. 93. 88. + 88. 93. 100. 105. 103. 97. 95. 96. 94. 88. 88. 92. 32. 32. 30. 39. + 72. 118. 152. 164. 176. 172. 162. 142. 102. 51. 38. 63. 110. 140. + 160. 168. 177. 179. 173. 173. 175. 178. 179. 175. 171. 166. 156. + 145. 127. 109. 58. 58. 38. 44. 48. 54. 51. 45. 48. 49. 42. 46. 53. + 50. 59. 45. 51. 79. 83. 61. 46. 51. 61. 61. 33. 62. 59. 52. 50. 39. + 39. 69. 53. 52. 95. 87. 50. 56. 44. 53. 78. 115. 122. 95. 138. 105. + 121. 111. 120. 73. 35. 56. 92. 42. 41. 88. 27. 38. 89. 58. 59. 120. + 108. 104. 93. 78. 63. 55. 56. 60. 50. 54. 64. 78. 90. 101. 114. 125. + 122. 130. 128. 121. 102. 63. 59. 99. 107. 120. 131. 133. 132. 134. + 135. 135. 141. 141. 141. 140. 139. 138. 137. 136. 131. 132. 134. + 136. 138. 140. 142. 143. 143. 144. 145. 148. 150. 152. 154. 155. + 158. 159. 161. 163. 165. 167. 169. 170. 177. 180. 184. 187. 189. + 192. 196. 198. 201. 203. 205. 206. 206. 207. 209. 211. 212. 221. + 206. 219. 223. 204. 144. 27. 83. 138. 137. 142. 140. 150. 148. 151. + 143. 143. 142. 141. 140. 140. 139. 139. 139. 140. 140. 140. 139. + 136. 133. 130. 125. 131. 128. 124. 128. 139. 170. 210. 211. 212. + 208. 202. 204. 212. 218. 220. 216. 206. 189. 167. 138. 116. 113. + 121. 108. 104. 99. 95. 96. 100. 105. 109. 101. 95. 88. 85. 87. 94. + 101. 106. 102. 95. 92. 94. 93. 89. 90. 96. 34. 32. 36. 42. 62. 108. + 150. 162. 172. 173. 167. 148. 104. 50. 41. 73. 107. 138. 158. 165. + 174. 177. 175. 178. 180. 178. 180. 182. 174. 158. 147. 145. 138. + 103. 51. 39. 50. 53. 57. 40. 37. 51. 56. 46. 40. 48. 58. 60. 49. 51. + 59. 68. 70. 62. 55. 52. 48. 48. 50. 62. 64. 44. 33. 46. 37. 73. 36. + 44. 105. 80. 38. 54. 81. 80. 84. 102. 122. 119. 110. 114. 98. 141. + 119. 136. 48. 37. 105. 46. 63. 43. 44. 52. 65. 61. 49. 71. 55. 66. + 86. 95. 80. 54. 44. 49. 46. 57. 70. 80. 94. 109. 121. 125. 131. 129. + 124. 130. 87. 53. 86. 94. 111. 126. 135. 131. 131. 138. 140. 135. + 138. 137. 137. 140. 143. 143. 139. 135. 134. 135. 136. 137. 138. + 139. 139. 139. 140. 143. 146. 147. 149. 150. 153. 156. 158. 159. + 161. 163. 165. 168. 170. 170. 174. 178. 183. 187. 190. 192. 195. + 197. 201. 202. 204. 205. 207. 207. 208. 208. 210. 221. 207. 215. + 213. 219. 179. 31. 90. 129. 143. 140. 149. 149. 141. 147. 141. 143. + 144. 144. 142. 141. 142. 142. 139. 140. 141. 140. 138. 135. 131. + 129. 127. 128. 130. 129. 126. 137. 169. 200. 206. 211. 209. 202. + 201. 209. 216. 218. 211. 208. 188. 152. 126. 117. 114. 110. 110. + 109. 102. 94. 94. 101. 103. 99. 87. 86. 86. 90. 95. 100. 103. 104. + 97. 101. 100. 93. 88. 92. 98. 101. 36. 33. 36. 41. 60. 105. 148. + 161. 171. 170. 164. 146. 106. 54. 43. 71. 106. 137. 158. 165. 174. + 177. 175. 178. 180. 178. 179. 180. 173. 158. 148. 146. 142. 107. 52. + 51. 52. 52. 50. 39. 44. 44. 40. 39. 52. 68. 70. 61. 44. 46. 54. 64. + 66. 61. 56. 56. 46. 47. 48. 58. 66. 51. 35. 38. 58. 47. 41. 81. 82. + 69. 85. 55. 89. 88. 86. 85. 93. 110. 120. 119. 92. 108. 121. 139. + 103. 54. 102. 38. 44. 39. 54. 55. 55. 59. 54. 64. 55. 56. 65. 72. + 65. 48. 41. 45. 50. 62. 75. 86. 97. 110. 120. 123. 128. 126. 128. + 121. 79. 58. 86. 100. 113. 127. 135. 132. 132. 138. 140. 136. 139. + 138. 138. 140. 142. 142. 138. 135. 134. 135. 136. 137. 138. 138. + 139. 139. 140. 143. 146. 147. 148. 150. 153. 155. 157. 158. 160. + 162. 164. 167. 168. 169. 172. 176. 181. 185. 188. 190. 193. 196. + 200. 201. 203. 205. 206. 207. 208. 208. 209. 219. 207. 216. 214. + 219. 190. 64. 95. 133. 146. 141. 149. 152. 145. 147. 141. 143. 144. + 143. 141. 139. 139. 139. 140. 140. 141. 141. 139. 136. 133. 132. + 128. 129. 132. 131. 128. 134. 156. 179. 198. 202. 202. 200. 203. + 213. 219. 219. 211. 206. 184. 149. 124. 117. 114. 110. 109. 106. 98. + 92. 95. 101. 101. 95. 78. 83. 90. 97. 101. 102. 102. 101. 93. 98. + 98. 93. 92. 95. 97. 97. 39. 35. 36. 39. 55. 101. 144. 159. 171. 169. + 162. 147. 111. 62. 48. 71. 105. 136. 157. 164. 174. 177. 175. 177. + 179. 177. 178. 178. 171. 160. 150. 147. 150. 115. 54. 67. 53. 52. + 40. 39. 37. 43. 51. 61. 75. 80. 66. 46. 41. 45. 53. 61. 62. 57. 54. + 56. 53. 54. 48. 51. 63. 59. 45. 40. 63. 42. 52. 94. 65. 59. 107. 73. + 56. 83. 116. 116. 101. 114. 129. 116. 86. 71. 91. 128. 129. 86. 104. + 62. 67. 38. 52. 62. 53. 54. 53. 60. 62. 53. 50. 54. 54. 48. 45. 48. + 55. 68. 83. 93. 102. 112. 120. 122. 124. 123. 133. 105. 67. 65. 85. + 108. 117. 129. 136. 134. 134. 140. 141. 138. 141. 140. 140. 141. + 142. 141. 138. 135. 135. 135. 136. 137. 137. 138. 139. 139. 140. + 143. 146. 147. 148. 150. 152. 155. 155. 156. 158. 160. 163. 165. + 167. 168. 171. 174. 179. 183. 185. 188. 191. 194. 199. 200. 202. + 204. 206. 207. 208. 208. 210. 214. 207. 217. 213. 218. 204. 113. + 101. 136. 149. 139. 141. 149. 146. 143. 145. 146. 148. 147. 144. + 142. 142. 143. 140. 140. 140. 140. 139. 136. 134. 132. 129. 131. + 135. 135. 132. 132. 142. 154. 179. 182. 186. 193. 204. 215. 219. + 217. 210. 201. 176. 142. 120. 114. 111. 107. 106. 101. 94. 91. 97. + 101. 96. 87. 69. 80. 95. 105. 107. 103. 99. 96. 89. 93. 95. 94. 96. + 99. 96. 90. 41. 36. 36. 36. 51. 95. 140. 156. 172. 170. 161. 148. + 118. 72. 55. 72. 104. 135. 156. 164. 173. 176. 174. 177. 178. 177. + 177. 175. 170. 161. 152. 147. 159. 124. 58. 81. 54. 51. 34. 44. 40. + 59. 76. 80. 74. 64. 51. 39. 43. 48. 57. 64. 61. 53. 50. 53. 62. 65. + 54. 46. 57. 64. 57. 52. 45. 66. 70. 66. 60. 59. 79. 100. 36. 59. + 112. 135. 122. 128. 133. 106. 95. 68. 65. 124. 121. 121. 106. 92. + 120. 43. 39. 65. 59. 48. 47. 61. 63. 53. 47. 48. 50. 48. 47. 50. 57. + 72. 89. 99. 107. 115. 120. 122. 122. 123. 132. 88. 57. 73. 86. 115. + 122. 131. 137. 136. 137. 141. 142. 139. 142. 142. 142. 142. 141. + 140. 138. 136. 136. 136. 136. 136. 137. 138. 138. 139. 141. 143. + 145. 147. 148. 149. 152. 154. 153. 154. 156. 158. 161. 163. 165. + 166. 170. 173. 178. 181. 184. 187. 191. 193. 197. 198. 201. 203. + 205. 207. 208. 208. 211. 211. 208. 217. 211. 214. 213. 160. 108. + 137. 148. 132. 125. 134. 139. 136. 142. 144. 146. 147. 146. 145. + 146. 147. 142. 141. 141. 140. 138. 135. 133. 132. 132. 135. 138. + 139. 137. 136. 138. 141. 153. 157. 167. 183. 203. 216. 218. 214. + 207. 193. 165. 134. 115. 110. 107. 103. 100. 95. 91. 94. 100. 99. + 89. 78. 69. 83. 100. 110. 108. 101. 95. 92. 87. 90. 92. 95. 99. 100. + 92. 81. 41. 37. 36. 35. 47. 91. 137. 153. 169. 168. 160. 148. 121. + 77. 58. 70. 102. 134. 155. 163. 172. 176. 174. 177. 177. 177. 176. + 174. 170. 163. 152. 144. 163. 128. 65. 87. 56. 50. 35. 49. 58. 69. + 74. 65. 50. 43. 46. 50. 43. 50. 61. 67. 62. 54. 52. 56. 60. 68. 60. + 49. 57. 63. 57. 53. 34. 82. 91. 42. 48. 62. 56. 115. 71. 45. 59. 88. + 93. 108. 124. 114. 83. 52. 51. 106. 119. 149. 148. 145. 120. 46. 40. + 60. 52. 46. 48. 61. 52. 49. 46. 46. 45. 42. 43. 46. 58. 75. 93. 104. + 110. 117. 122. 124. 123. 124. 123. 73. 54. 79. 91. 120. 127. 132. + 136. 137. 138. 141. 142. 140. 143. 144. 144. 143. 141. 140. 139. + 139. 137. 137. 136. 136. 136. 137. 138. 139. 141. 143. 145. 147. + 147. 148. 151. 153. 152. 153. 155. 157. 159. 162. 164. 164. 171. + 173. 177. 180. 183. 186. 191. 194. 195. 196. 199. 202. 205. 207. + 208. 209. 212. 210. 210. 215. 208. 210. 216. 192. 123. 138. 141. + 122. 107. 115. 127. 125. 129. 132. 136. 139. 141. 143. 145. 147. + 146. 145. 144. 142. 140. 138. 136. 134. 135. 139. 142. 143. 143. + 142. 141. 139. 134. 140. 156. 181. 206. 218. 218. 213. 206. 187. + 156. 129. 114. 109. 105. 101. 92. 91. 92. 98. 100. 94. 83. 74. 79. + 90. 103. 108. 104. 96. 91. 89. 87. 90. 92. 95. 99. 98. 86. 73. 39. + 36. 36. 34. 45. 88. 133. 151. 164. 165. 160. 147. 121. 79. 58. 67. + 101. 133. 154. 162. 172. 175. 174. 177. 176. 178. 177. 174. 171. + 164. 152. 139. 156. 125. 72. 86. 60. 48. 39. 50. 55. 56. 55. 51. 47. + 45. 46. 47. 44. 51. 62. 67. 62. 55. 59. 67. 51. 61. 58. 53. 59. 59. + 48. 43. 42. 78. 93. 46. 38. 59. 66. 113. 101. 60. 48. 56. 45. 52. + 94. 131. 101. 49. 52. 70. 101. 121. 169. 160. 65. 45. 56. 50. 37. + 49. 54. 55. 45. 47. 48. 47. 44. 43. 46. 50. 62. 80. 99. 108. 113. + 119. 124. 126. 123. 124. 104. 63. 59. 84. 101. 124. 131. 133. 136. + 138. 139. 141. 141. 140. 143. 144. 144. 143. 141. 140. 141. 142. + 138. 138. 136. 135. 135. 136. 138. 139. 141. 143. 145. 146. 146. + 147. 150. 152. 152. 152. 154. 157. 159. 161. 163. 164. 170. 173. + 176. 179. 181. 185. 190. 193. 193. 195. 198. 201. 204. 207. 208. + 209. 212. 210. 214. 214. 208. 210. 215. 208. 149. 137. 126. 109. 93. + 100. 112. 110. 117. 121. 126. 131. 135. 139. 143. 146. 146. 145. + 144. 143. 142. 141. 140. 139. 138. 143. 147. 146. 146. 146. 143. + 139. 129. 137. 158. 189. 213. 222. 219. 214. 203. 180. 149. 125. + 113. 108. 102. 97. 87. 90. 95. 99. 95. 85. 79. 78. 92. 97. 103. 103. + 98. 93. 89. 88. 92. 94. 95. 95. 95. 91. 78. 65. 36. 34. 35. 34. 44. + 86. 131. 149. 163. 167. 164. 151. 123. 81. 60. 69. 100. 132. 153. + 161. 171. 175. 173. 177. 175. 178. 178. 175. 172. 166. 150. 135. + 142. 117. 78. 82. 66. 46. 42. 45. 44. 46. 49. 52. 53. 50. 45. 43. + 51. 56. 62. 63. 56. 53. 63. 77. 55. 56. 48. 47. 56. 54. 41. 37. 46. + 80. 64. 52. 53. 50. 81. 112. 112. 85. 70. 63. 39. 25. 60. 114. 130. + 67. 61. 80. 83. 78. 129. 106. 33. 47. 63. 45. 37. 54. 52. 50. 48. + 48. 46. 44. 45. 50. 57. 61. 70. 87. 105. 113. 115. 119. 125. 127. + 121. 122. 81. 56. 69. 89. 114. 129. 133. 133. 134. 138. 140. 140. + 140. 140. 142. 144. 145. 143. 141. 140. 142. 145. 139. 138. 136. + 135. 135. 136. 138. 139. 141. 143. 145. 146. 146. 147. 149. 151. + 152. 153. 154. 157. 159. 161. 163. 164. 168. 171. 174. 176. 179. + 183. 188. 192. 192. 194. 197. 200. 204. 206. 208. 209. 210. 211. + 217. 213. 210. 215. 215. 214. 176. 132. 102. 91. 82. 88. 97. 89. + 101. 105. 111. 117. 122. 127. 131. 135. 137. 137. 137. 138. 139. + 140. 141. 142. 140. 148. 152. 150. 147. 145. 139. 133. 133. 143. + 167. 198. 219. 222. 216. 212. 195. 169. 137. 116. 108. 103. 95. 88. + 87. 92. 98. 97. 85. 74. 78. 88. 101. 101. 100. 98. 95. 92. 90. 88. + 97. 99. 98. 94. 90. 84. 72. 60. 34. 33. 35. 34. 44. 85. 130. 147. + 165. 172. 169. 156. 127. 85. 64. 72. 100. 131. 153. 161. 171. 175. + 173. 176. 175. 179. 179. 176. 173. 166. 149. 132. 130. 110. 81. 79. + 70. 44. 44. 40. 52. 53. 53. 49. 42. 40. 48. 58. 60. 62. 63. 59. 49. + 48. 62. 80. 68. 57. 38. 36. 50. 50. 41. 41. 41. 94. 30. 47. 80. 42. + 81. 118. 132. 98. 66. 61. 59. 42. 44. 72. 82. 42. 45. 128. 102. 97. + 117. 84. 45. 50. 56. 45. 50. 57. 44. 50. 49. 45. 39. 36. 42. 53. 63. + 67. 76. 93. 110. 116. 116. 120. 125. 127. 119. 121. 67. 53. 76. 92. + 124. 133. 134. 133. 134. 137. 140. 139. 139. 139. 141. 143. 145. + 144. 141. 141. 143. 146. 140. 138. 136. 135. 135. 136. 138. 139. + 141. 143. 145. 146. 146. 147. 149. 151. 152. 153. 154. 157. 159. + 162. 163. 164. 167. 169. 172. 174. 177. 181. 186. 190. 191. 193. + 196. 200. 204. 206. 208. 209. 209. 211. 218. 212. 212. 219. 215. + 216. 191. 126. 83. 76. 74. 81. 85. 72. 83. 87. 93. 99. 104. 109. + 114. 117. 126. 127. 128. 130. 133. 136. 139. 141. 141. 151. 157. + 152. 146. 141. 134. 125. 137. 147. 173. 204. 222. 220. 212. 208. + 186. 160. 127. 108. 102. 96. 86. 78. 88. 94. 100. 94. 77. 67. 78. + 96. 104. 102. 98. 96. 95. 93. 91. 89. 101. 103. 100. 93. 86. 79. 67. + 57. 35. 33. 35. 38. 44. 68. 117. 161. 170. 174. 175. 156. 136. 96. + 54. 67. 96. 128. 150. 159. 169. 174. 172. 176. 177. 173. 178. 180. + 172. 167. 157. 139. 129. 105. 74. 77. 79. 44. 30. 54. 64. 53. 45. + 44. 43. 44. 52. 62. 64. 46. 69. 54. 58. 50. 60. 64. 66. 53. 49. 47. + 42. 46. 50. 44. 47. 49. 48. 84. 62. 102. 102. 100. 130. 146. 86. 50. + 61. 87. 54. 51. 61. 44. 56. 135. 55. 104. 121. 62. 51. 45. 40. 40. + 45. 49. 49. 47. 44. 42. 40. 43. 50. 60. 69. 74. 90. 106. 116. 115. + 114. 117. 119. 116. 124. 81. 49. 60. 87. 107. 123. 137. 133. 134. + 135. 137. 139. 141. 142. 143. 145. 143. 141. 140. 139. 141. 143. + 144. 142. 137. 136. 139. 138. 133. 133. 138. 137. 140. 142. 143. + 143. 144. 147. 149. 151. 152. 153. 155. 157. 159. 161. 161. 167. + 168. 170. 172. 174. 178. 184. 188. 188. 192. 197. 201. 203. 205. + 207. 209. 210. 211. 212. 213. 215. 216. 218. 218. 213. 111. 80. 81. + 78. 85. 72. 72. 73. 78. 84. 88. 89. 90. 94. 97. 97. 103. 111. 115. + 118. 123. 132. 139. 138. 154. 165. 159. 145. 135. 132. 132. 131. + 152. 185. 214. 225. 218. 207. 200. 173. 148. 119. 101. 93. 86. 80. + 77. 88. 97. 93. 75. 66. 76. 91. 99. 106. 98. 94. 95. 93. 89. 91. 96. + 106. 101. 96. 91. 81. 66. 56. 53. 38. 33. 30. 32. 41. 68. 117. 161. + 170. 174. 176. 159. 142. 103. 59. 68. 96. 128. 150. 158. 169. 174. + 173. 176. 177. 173. 179. 181. 173. 167. 156. 137. 118. 115. 83. 85. + 81. 42. 37. 53. 51. 48. 47. 46. 43. 43. 54. 68. 52. 45. 71. 54. 53. + 50. 64. 70. 68. 58. 55. 51. 41. 43. 51. 49. 59. 41. 56. 78. 32. 84. + 114. 88. 117. 145. 133. 89. 69. 51. 55. 80. 70. 87. 89. 128. 60. 69. + 66. 41. 53. 48. 43. 43. 46. 48. 46. 43. 44. 42. 41. 44. 52. 63. 73. + 79. 90. 110. 123. 120. 117. 121. 122. 118. 102. 68. 48. 66. 98. 117. + 128. 136. 134. 135. 136. 137. 139. 140. 141. 142. 143. 143. 142. + 141. 141. 141. 142. 143. 142. 137. 136. 139. 138. 134. 134. 138. + 137. 139. 142. 143. 143. 144. 146. 148. 150. 151. 153. 155. 157. + 159. 160. 161. 166. 168. 170. 171. 173. 178. 183. 187. 187. 191. + 196. 200. 202. 204. 207. 209. 210. 210. 211. 213. 215. 216. 217. + 218. 215. 131. 79. 82. 82. 90. 78. 80. 72. 74. 77. 78. 77. 77. 77. + 77. 81. 86. 91. 94. 97. 103. 113. 120. 139. 146. 152. 151. 150. 150. + 147. 142. 141. 164. 193. 214. 221. 215. 200. 186. 154. 133. 107. 89. + 79. 75. 76. 80. 90. 95. 90. 76. 72. 84. 97. 101. 98. 94. 93. 95. 93. + 90. 92. 98. 107. 101. 95. 89. 79. 65. 56. 54. 41. 34. 28. 29. 38. + 66. 117. 161. 171. 175. 177. 162. 149. 112. 64. 67. 96. 128. 150. + 158. 169. 174. 173. 176. 176. 174. 180. 181. 173. 168. 155. 133. 96. + 122. 87. 88. 78. 37. 49. 51. 44. 41. 41. 45. 49. 52. 58. 65. 43. 46. + 74. 54. 45. 51. 65. 71. 68. 61. 61. 55. 41. 42. 52. 52. 63. 46. 55. + 60. 27. 55. 91. 88. 105. 120. 147. 127. 112. 69. 80. 95. 113. 120. + 72. 57. 38. 44. 47. 63. 54. 50. 46. 45. 47. 46. 43. 39. 43. 42. 42. + 45. 54. 66. 79. 86. 96. 115. 124. 118. 117. 125. 123. 112. 70. 53. + 52. 80. 112. 128. 133. 136. 136. 136. 137. 138. 138. 139. 140. 140. + 141. 142. 142. 143. 143. 142. 142. 142. 142. 138. 137. 138. 137. + 135. 135. 137. 137. 139. 141. 142. 142. 143. 145. 147. 150. 150. + 152. 154. 156. 158. 159. 160. 165. 166. 169. 171. 173. 177. 182. + 186. 187. 190. 196. 199. 201. 203. 206. 208. 209. 210. 211. 212. + 214. 216. 217. 217. 218. 163. 81. 82. 86. 97. 87. 90. 83. 81. 79. + 78. 75. 72. 67. 64. 64. 66. 67. 67. 69. 76. 86. 94. 123. 126. 132. + 144. 161. 171. 166. 155. 155. 181. 205. 215. 218. 215. 195. 172. + 136. 116. 92. 74. 65. 64. 72. 82. 88. 89. 85. 78. 82. 96. 103. 102. + 90. 90. 92. 94. 92. 91. 95. 102. 108. 100. 92. 85. 74. 62. 54. 54. + 42. 39. 37. 36. 40. 65. 114. 160. 171. 176. 179. 165. 155. 119. 67. + 64. 95. 127. 149. 158. 169. 174. 173. 177. 176. 175. 181. 181. 174. + 169. 154. 128. 79. 124. 82. 80. 70. 35. 59. 47. 47. 38. 34. 43. 57. + 65. 61. 55. 42. 50. 73. 54. 41. 55. 62. 64. 65. 59. 61. 57. 46. 46. + 52. 49. 50. 61. 49. 41. 52. 36. 44. 90. 107. 105. 134. 142. 135. + 111. 112. 100. 95. 104. 73. 49. 52. 46. 42. 57. 51. 49. 47. 47. 47. + 45. 41. 38. 40. 41. 43. 48. 57. 71. 85. 94. 108. 116. 116. 111. 118. + 126. 113. 89. 43. 47. 66. 98. 124. 133. 135. 136. 137. 137. 138. + 138. 138. 138. 139. 139. 139. 140. 142. 144. 144. 143. 142. 141. + 141. 139. 138. 138. 137. 136. 136. 137. 137. 139. 141. 142. 141. + 142. 144. 146. 148. 149. 151. 153. 155. 157. 158. 159. 162. 165. + 167. 170. 172. 175. 180. 183. 185. 189. 194. 198. 200. 202. 205. + 207. 208. 209. 210. 212. 213. 215. 216. 217. 219. 192. 91. 82. 89. + 101. 96. 99. 97. 93. 88. 84. 81. 76. 68. 62. 59. 57. 53. 49. 49. 54. + 62. 69. 88. 100. 122. 151. 178. 189. 178. 161. 158. 187. 209. 212. + 214. 214. 190. 158. 122. 102. 79. 65. 60. 63. 73. 83. 79. 80. 80. + 84. 95. 106. 107. 100. 87. 88. 90. 89. 88. 91. 98. 105. 106. 97. 88. + 79. 69. 58. 52. 53. 46. 50. 55. 54. 50. 66. 112. 157. 171. 178. 181. + 167. 159. 123. 69. 63. 95. 127. 149. 158. 170. 175. 174. 178. 175. + 176. 182. 182. 175. 171. 152. 122. 82. 129. 81. 68. 60. 35. 60. 41. + 46. 45. 45. 49. 56. 61. 59. 55. 45. 49. 64. 53. 42. 63. 62. 59. 62. + 54. 56. 58. 52. 52. 52. 43. 34. 64. 56. 41. 57. 43. 34. 65. 92. 106. + 131. 148. 119. 124. 118. 101. 81. 91. 109. 85. 51. 34. 42. 47. 46. + 46. 46. 47. 47. 45. 42. 39. 39. 41. 46. 53. 62. 76. 90. 100. 115. + 115. 113. 115. 126. 123. 92. 56. 35. 56. 88. 115. 128. 132. 134. + 136. 138. 138. 138. 138. 138. 138. 138. 138. 138. 140. 142. 145. + 145. 144. 142. 140. 141. 141. 139. 137. 137. 137. 137. 137. 137. + 138. 140. 141. 140. 141. 143. 145. 147. 148. 149. 151. 153. 155. + 157. 158. 160. 163. 166. 169. 171. 174. 178. 181. 184. 188. 193. + 197. 199. 201. 203. 205. 207. 208. 209. 211. 212. 214. 215. 216. + 218. 211. 115. 83. 89. 100. 101. 103. 102. 98. 93. 89. 86. 81. 73. + 67. 63. 59. 51. 44. 39. 41. 45. 50. 56. 88. 133. 173. 197. 198. 178. + 158. 159. 188. 208. 209. 211. 210. 181. 143. 104. 84. 64. 59. 64. + 71. 78. 84. 69. 73. 80. 92. 105. 111. 104. 93. 88. 88. 87. 85. 85. + 92. 101. 108. 102. 93. 83. 75. 65. 55. 51. 53. 59. 65. 73. 73. 66. + 74. 112. 152. 170. 180. 185. 170. 161. 128. 73. 66. 94. 126. 149. + 158. 170. 175. 174. 178. 175. 177. 183. 182. 175. 172. 151. 117. 97. + 135. 89. 63. 53. 38. 56. 41. 42. 55. 64. 57. 46. 45. 53. 61. 47. 45. + 54. 55. 46. 71. 62. 60. 62. 53. 55. 58. 53. 53. 51. 39. 32. 52. 64. + 57. 39. 63. 62. 31. 50. 82. 115. 147. 127. 143. 117. 84. 116. 94. + 116. 89. 31. 34. 59. 55. 42. 43. 44. 44. 44. 43. 42. 41. 39. 44. 52. + 60. 70. 82. 97. 107. 115. 114. 117. 125. 126. 106. 68. 36. 46. 75. + 109. 126. 129. 130. 133. 137. 137. 137. 138. 138. 138. 138. 139. + 139. 138. 139. 142. 144. 145. 144. 143. 141. 140. 142. 141. 137. + 136. 138. 138. 136. 136. 138. 140. 140. 139. 140. 141. 143. 146. + 147. 148. 150. 152. 154. 156. 156. 158. 161. 165. 168. 170. 173. + 176. 179. 183. 187. 192. 196. 198. 200. 202. 204. 207. 207. 208. + 210. 212. 213. 214. 215. 216. 218. 149. 86. 88. 97. 104. 105. 105. + 103. 100. 97. 93. 88. 82. 78. 71. 65. 56. 47. 40. 37. 37. 38. 43. + 90. 152. 196. 209. 198. 174. 154. 172. 196. 213. 213. 211. 201. 165. + 123. 80. 64. 53. 57. 69. 77. 80. 82. 67. 74. 86. 99. 108. 107. 96. + 86. 86. 87. 84. 82. 86. 97. 105. 108. 99. 90. 81. 73. 64. 56. 53. + 55. 79. 81. 85. 86. 81. 87. 115. 146. 166. 180. 187. 172. 164. 133. + 81. 75. 94. 126. 148. 158. 170. 175. 175. 178. 174. 178. 184. 182. + 176. 173. 150. 112. 103. 132. 98. 61. 48. 42. 50. 48. 47. 60. 65. + 55. 42. 41. 50. 57. 51. 44. 50. 60. 48. 71. 58. 62. 65. 58. 59. 58. + 49. 48. 48. 41. 44. 47. 49. 66. 41. 76. 66. 34. 30. 51. 82. 116. + 138. 155. 134. 96. 110. 86. 117. 107. 46. 54. 57. 39. 41. 42. 42. + 42. 41. 40. 40. 40. 41. 49. 60. 69. 78. 90. 103. 112. 116. 115. 120. + 121. 102. 70. 49. 44. 69. 95. 121. 130. 130. 132. 135. 136. 136. + 137. 137. 138. 138. 139. 139. 140. 138. 139. 141. 143. 144. 144. + 143. 143. 140. 143. 142. 137. 136. 139. 139. 136. 136. 138. 140. + 140. 139. 139. 141. 142. 145. 146. 147. 149. 151. 153. 155. 156. + 156. 160. 164. 167. 169. 172. 175. 177. 182. 186. 191. 195. 197. + 199. 201. 203. 206. 207. 208. 209. 211. 213. 214. 214. 216. 217. + 185. 90. 88. 94. 107. 105. 106. 107. 107. 104. 98. 93. 90. 89. 79. + 74. 65. 56. 48. 43. 38. 36. 41. 94. 161. 203. 210. 194. 172. 157. + 185. 202. 213. 211. 201. 178. 131. 87. 62. 55. 54. 63. 72. 76. 75. + 75. 74. 82. 95. 105. 106. 98. 87. 80. 81. 82. 81. 83. 92. 105. 109. + 106. 98. 90. 81. 75. 67. 59. 57. 59. 95. 91. 90. 91. 91. 96. 118. + 141. 164. 180. 189. 174. 166. 136. 87. 83. 94. 126. 148. 158. 170. + 175. 175. 179. 174. 178. 185. 182. 176. 173. 149. 110. 98. 123. 101. + 59. 46. 45. 48. 56. 59. 59. 54. 46. 45. 50. 50. 45. 57. 47. 52. 66. + 48. 66. 52. 61. 70. 64. 64. 58. 44. 41. 47. 45. 57. 53. 23. 63. 66. + 77. 43. 62. 49. 49. 67. 73. 115. 132. 152. 144. 90. 90. 130. 118. + 43. 45. 43. 44. 41. 42. 42. 41. 39. 37. 38. 38. 44. 53. 65. 75. 84. + 95. 107. 116. 120. 118. 119. 108. 72. 37. 39. 64. 87. 107. 125. 129. + 130. 135. 137. 135. 136. 136. 137. 138. 138. 139. 140. 140. 139. + 140. 141. 142. 143. 144. 144. 144. 140. 143. 142. 136. 136. 140. + 140. 136. 136. 138. 139. 139. 138. 138. 140. 142. 145. 145. 147. + 149. 151. 153. 154. 155. 156. 159. 163. 167. 169. 171. 174. 177. + 182. 186. 191. 194. 197. 198. 201. 203. 206. 206. 208. 209. 211. + 212. 213. 214. 216. 214. 207. 93. 88. 92. 108. 105. 103. 106. 107. + 104. 97. 92. 90. 91. 85. 80. 72. 64. 57. 50. 43. 39. 40. 94. 159. + 199. 205. 191. 174. 163. 187. 198. 204. 199. 183. 149. 95. 49. 57. + 57. 62. 70. 74. 71. 68. 68. 82. 91. 102. 108. 103. 91. 81. 77. 75. + 78. 80. 85. 98. 112. 112. 105. 98. 90. 83. 77. 70. 62. 60. 62. 83. + 93. 92. 88. 98. 110. 127. 147. 170. 179. 185. 181. 168. 144. 104. + 70. 100. 121. 145. 161. 170. 175. 177. 175. 174. 178. 180. 188. 176. + 167. 151. 98. 111. 109. 103. 60. 48. 58. 40. 48. 43. 54. 46. 46. 44. + 43. 57. 52. 59. 51. 46. 52. 46. 45. 61. 61. 66. 64. 41. 64. 72. 41. + 43. 44. 45. 70. 60. 38. 54. 71. 63. 50. 59. 74. 56. 71. 73. 65. 109. + 139. 112. 128. 66. 38. 54. 43. 42. 44. 51. 46. 42. 41. 38. 36. 40. + 47. 42. 56. 74. 85. 91. 101. 115. 127. 120. 119. 102. 68. 36. 33. + 61. 90. 117. 121. 125. 129. 130. 132. 134. 136. 136. 137. 138. 139. + 139. 139. 138. 138. 137. 138. 141. 143. 144. 143. 142. 141. 143. + 143. 142. 140. 139. 138. 137. 136. 136. 136. 137. 138. 139. 139. + 139. 139. 144. 145. 147. 148. 149. 150. 154. 156. 156. 159. 161. + 163. 164. 166. 170. 173. 179. 183. 187. 191. 194. 198. 202. 205. + 205. 206. 207. 209. 211. 212. 212. 212. 213. 214. 218. 138. 76. 90. + 92. 108. 107. 108. 108. 106. 101. 97. 95. 94. 84. 82. 78. 70. 61. + 54. 49. 47. 55. 91. 151. 192. 198. 195. 192. 184. 189. 194. 199. + 186. 142. 89. 56. 50. 53. 58. 65. 70. 72. 72. 73. 74. 92. 102. 108. + 102. 88. 79. 76. 77. 78. 78. 83. 95. 107. 112. 109. 103. 91. 88. 83. + 75. 68. 63. 62. 62. 77. 92. 97. 98. 107. 117. 132. 153. 171. 180. + 184. 179. 167. 145. 109. 77. 100. 121. 145. 161. 169. 175. 177. 175. + 174. 180. 181. 186. 175. 169. 152. 94. 117. 109. 93. 51. 44. 55. 41. + 47. 45. 52. 45. 50. 48. 43. 57. 56. 49. 45. 47. 53. 49. 52. 63. 60. + 64. 56. 49. 72. 77. 50. 45. 55. 36. 54. 78. 78. 32. 60. 77. 58. 61. + 58. 98. 55. 87. 97. 94. 72. 129. 136. 88. 50. 53. 52. 45. 40. 45. + 43. 43. 45. 45. 43. 46. 51. 73. 75. 78. 82. 88. 98. 110. 118. 116. + 92. 60. 40. 41. 61. 86. 103. 119. 122. 126. 129. 131. 132. 134. 136. + 137. 137. 138. 139. 139. 139. 139. 139. 137. 138. 141. 143. 144. + 143. 142. 141. 144. 144. 143. 141. 140. 139. 138. 137. 137. 137. + 138. 139. 139. 139. 139. 139. 143. 145. 147. 148. 148. 150. 153. + 156. 156. 158. 161. 162. 164. 166. 170. 173. 177. 180. 185. 188. + 191. 195. 199. 203. 204. 205. 207. 209. 210. 211. 212. 212. 211. + 219. 213. 165. 81. 90. 91. 104. 105. 107. 107. 106. 101. 98. 96. 95. + 89. 87. 83. 77. 71. 66. 63. 62. 59. 88. 143. 186. 200. 206. 207. + 198. 190. 177. 161. 139. 106. 71. 54. 55. 56. 63. 69. 70. 68. 70. + 77. 84. 99. 103. 104. 96. 84. 77. 77. 79. 78. 82. 90. 102. 110. 111. + 105. 98. 94. 87. 78. 70. 66. 65. 65. 65. 70. 90. 102. 107. 115. 119. + 131. 151. 169. 177. 181. 175. 164. 145. 112. 83. 100. 120. 144. 160. + 169. 175. 177. 176. 175. 183. 182. 183. 174. 171. 153. 89. 124. 111. + 85. 45. 41. 53. 45. 49. 48. 51. 45. 56. 54. 43. 56. 59. 50. 44. 47. + 48. 47. 60. 72. 71. 67. 47. 60. 81. 82. 60. 42. 58. 48. 54. 86. 83. + 48. 56. 79. 59. 58. 62. 104. 53. 84. 126. 121. 64. 76. 82. 78. 48. + 37. 49. 47. 48. 46. 43. 41. 41. 39. 38. 42. 48. 64. 70. 82. 98. 110. + 114. 108. 102. 66. 50. 37. 47. 74. 100. 111. 110. 121. 124. 128. + 130. 131. 133. 135. 137. 137. 138. 139. 140. 140. 140. 140. 139. + 137. 139. 141. 142. 143. 143. 142. 141. 145. 145. 144. 143. 142. + 141. 140. 139. 138. 138. 138. 139. 139. 139. 139. 140. 143. 144. + 146. 147. 148. 149. 153. 155. 156. 158. 160. 162. 163. 166. 169. + 172. 174. 177. 182. 185. 188. 192. 196. 199. 203. 204. 206. 208. + 210. 211. 212. 212. 209. 222. 208. 197. 97. 84. 91. 98. 103. 104. + 106. 105. 102. 99. 97. 97. 95. 92. 88. 84. 80. 79. 79. 79. 79. 99. + 144. 186. 206. 213. 210. 195. 174. 148. 116. 91. 72. 57. 54. 60. 63. + 68. 72. 70. 68. 73. 87. 99. 106. 104. 97. 87. 78. 73. 75. 79. 80. + 88. 100. 110. 113. 109. 101. 94. 95. 85. 72. 64. 64. 67. 67. 66. 62. + 84. 101. 110. 114. 112. 120. 140. 163. 173. 178. 173. 162. 142. 110. + 82. 100. 120. 143. 159. 168. 175. 177. 177. 176. 185. 183. 181. 173. + 173. 155. 88. 121. 112. 82. 47. 42. 49. 49. 54. 51. 51. 46. 61. 58. + 41. 51. 58. 65. 49. 49. 41. 42. 66. 81. 88. 76. 42. 65. 86. 88. 71. + 39. 49. 46. 66. 88. 59. 77. 50. 71. 86. 47. 71. 62. 78. 69. 116. + 147. 102. 62. 57. 87. 69. 38. 40. 37. 51. 48. 42. 37. 35. 35. 37. + 47. 57. 78. 83. 92. 100. 99. 85. 63. 47. 35. 43. 59. 81. 102. 115. + 117. 115. 124. 126. 129. 131. 132. 133. 135. 138. 137. 138. 139. + 140. 140. 140. 140. 140. 138. 139. 140. 142. 143. 143. 142. 142. + 146. 146. 145. 144. 143. 142. 142. 141. 140. 140. 139. 139. 139. + 140. 140. 140. 142. 144. 146. 146. 147. 149. 152. 155. 155. 157. + 159. 161. 162. 165. 169. 172. 173. 176. 180. 184. 186. 190. 194. + 197. 202. 203. 205. 207. 209. 211. 211. 211. 211. 220. 208. 215. + 123. 72. 95. 91. 99. 101. 104. 104. 102. 100. 100. 100. 97. 94. 89. + 86. 86. 87. 88. 89. 93. 107. 147. 190. 211. 215. 200. 175. 138. 115. + 89. 72. 63. 59. 60. 65. 72. 72. 71. 71. 75. 85. 100. 112. 108. 100. + 90. 80. 72. 68. 70. 76. 85. 95. 107. 115. 114. 107. 100. 95. 92. 80. + 66. 62. 65. 69. 67. 64. 53. 74. 93. 104. 109. 105. 112. 133. 158. + 171. 179. 175. 164. 143. 110. 82. 99. 119. 142. 157. 167. 174. 178. + 178. 177. 185. 183. 182. 173. 173. 157. 95. 104. 104. 77. 50. 43. + 43. 49. 55. 52. 53. 48. 63. 59. 40. 48. 53. 77. 50. 52. 41. 42. 67. + 78. 93. 81. 40. 63. 88. 96. 89. 52. 45. 31. 61. 81. 70. 58. 38. 66. + 117. 67. 58. 41. 90. 74. 97. 131. 125. 82. 49. 73. 72. 45. 40. 36. + 52. 43. 40. 39. 42. 45. 49. 58. 67. 80. 76. 70. 61. 53. 46. 43. 42. + 68. 79. 92. 101. 105. 109. 117. 123. 126. 128. 130. 131. 131. 132. + 135. 137. 137. 138. 139. 140. 140. 140. 139. 139. 138. 139. 140. + 141. 142. 142. 143. 143. 146. 146. 146. 145. 144. 144. 143. 143. + 142. 141. 140. 139. 139. 140. 141. 141. 141. 143. 145. 146. 146. + 148. 151. 154. 154. 156. 159. 160. 161. 164. 168. 171. 173. 176. + 180. 183. 186. 189. 193. 196. 200. 202. 204. 206. 209. 210. 211. + 211. 214. 214. 212. 215. 155. 66. 98. 87. 95. 98. 101. 103. 102. + 102. 102. 103. 101. 97. 92. 91. 92. 94. 95. 95. 88. 101. 140. 182. + 203. 202. 178. 146. 101. 90. 78. 71. 68. 68. 70. 74. 78. 73. 70. 75. + 87. 100. 110. 115. 103. 93. 83. 76. 68. 63. 67. 75. 91. 100. 111. + 115. 112. 105. 100. 98. 84. 73. 63. 62. 68. 70. 64. 57. 46. 63. 79. + 93. 101. 100. 109. 133. 156. 170. 181. 179. 167. 147. 116. 89. 99. + 118. 141. 156. 166. 174. 178. 178. 179. 182. 181. 184. 174. 170. + 160. 108. 82. 90. 66. 50. 44. 37. 48. 52. 50. 55. 52. 64. 59. 43. + 49. 49. 81. 45. 53. 47. 48. 66. 67. 88. 75. 41. 57. 91. 105. 106. + 81. 53. 50. 47. 60. 103. 30. 43. 59. 90. 118. 52. 59. 68. 89. 108. + 121. 148. 109. 56. 46. 52. 44. 41. 40. 46. 43. 43. 47. 51. 51. 47. + 48. 52. 45. 45. 45. 44. 48. 59. 77. 90. 97. 102. 108. 113. 117. 120. + 124. 127. 127. 129. 130. 130. 130. 131. 134. 137. 136. 137. 138. + 138. 139. 139. 138. 138. 139. 139. 140. 141. 141. 142. 143. 143. + 146. 146. 145. 145. 144. 144. 144. 143. 144. 143. 141. 140. 139. + 140. 141. 142. 140. 142. 144. 145. 145. 147. 150. 153. 153. 155. + 158. 159. 161. 163. 167. 170. 174. 177. 180. 183. 185. 188. 192. + 195. 199. 200. 203. 205. 208. 210. 211. 211. 215. 211. 215. 212. + 183. 77. 94. 85. 92. 95. 99. 102. 102. 103. 104. 106. 106. 102. 98. + 98. 101. 104. 104. 103. 94. 101. 130. 162. 172. 165. 138. 106. 84. + 80. 76. 74. 73. 75. 79. 81. 78. 74. 74. 83. 98. 109. 111. 108. 92. + 83. 76. 72. 66. 62. 70. 83. 99. 106. 113. 115. 111. 104. 99. 97. 76. + 68. 61. 62. 67. 68. 60. 52. 44. 55. 65. 79. 90. 92. 104. 129. 153. + 168. 178. 176. 167. 150. 123. 99. 99. 118. 141. 156. 165. 174. 178. + 179. 181. 179. 179. 188. 175. 167. 162. 122. 68. 78. 53. 47. 47. 39. + 51. 50. 45. 57. 55. 64. 60. 50. 56. 50. 90. 42. 52. 51. 51. 64. 60. + 92. 63. 43. 52. 91. 107. 113. 107. 62. 64. 41. 59. 107. 58. 48. 47. + 55. 119. 78. 71. 58. 84. 124. 125. 138. 136. 103. 67. 58. 46. 37. + 44. 37. 50. 48. 47. 48. 44. 39. 40. 44. 50. 57. 65. 72. 77. 85. 94. + 102. 104. 109. 117. 124. 128. 129. 128. 127. 128. 129. 130. 129. + 129. 130. 133. 136. 135. 135. 136. 137. 138. 138. 137. 137. 139. + 139. 140. 140. 141. 142. 143. 144. 145. 145. 145. 144. 144. 144. + 144. 143. 145. 144. 142. 140. 139. 140. 142. 143. 140. 141. 143. + 144. 145. 146. 150. 152. 153. 155. 157. 159. 160. 163. 166. 170. + 173. 176. 179. 182. 184. 187. 191. 194. 198. 199. 202. 205. 207. + 209. 210. 211. 212. 213. 212. 216. 200. 102. 84. 85. 89. 93. 97. + 101. 103. 104. 106. 108. 107. 103. 101. 104. 109. 113. 112. 110. + 109. 107. 120. 134. 133. 125. 106. 82. 84. 83. 81. 81. 83. 84. 82. + 78. 72. 74. 81. 93. 105. 108. 102. 95. 82. 74. 70. 69. 64. 64. 79. + 99. 106. 110. 115. 116. 112. 103. 95. 90. 71. 65. 60. 60. 64. 63. + 57. 50. 46. 52. 57. 69. 81. 83. 96. 122. 149. 163. 173. 171. 163. + 149. 126. 105. 98. 118. 140. 155. 165. 174. 178. 179. 182. 177. 178. + 190. 176. 165. 163. 131. 65. 73. 44. 44. 51. 44. 56. 50. 41. 58. 57. + 64. 62. 55. 62. 52. 103. 44. 50. 49. 49. 62. 61. 103. 53. 46. 50. + 90. 103. 111. 118. 64. 37. 41. 85. 90. 110. 36. 39. 65. 64. 110. 63. + 76. 68. 117. 111. 83. 97. 106. 76. 61. 43. 34. 59. 53. 52. 46. 41. + 39. 40. 43. 53. 64. 69. 73. 80. 88. 94. 100. 106. 109. 118. 123. + 126. 123. 117. 117. 124. 131. 128. 129. 129. 129. 128. 129. 132. + 135. 134. 135. 136. 136. 137. 137. 136. 136. 140. 140. 140. 140. + 141. 142. 143. 144. 145. 144. 144. 144. 144. 144. 143. 143. 146. + 144. 142. 140. 139. 140. 142. 143. 139. 141. 143. 144. 144. 146. + 149. 152. 152. 154. 157. 158. 160. 162. 166. 169. 172. 175. 178. + 181. 183. 186. 189. 192. 197. 199. 201. 204. 207. 209. 210. 211. + 209. 217. 209. 222. 207. 123. 76. 86. 87. 91. 97. 100. 103. 105. + 107. 109. 105. 102. 101. 106. 113. 118. 117. 114. 114. 106. 109. + 113. 109. 107. 100. 85. 88. 88. 87. 90. 94. 92. 81. 70. 67. 75. 88. + 100. 106. 103. 94. 86. 76. 69. 65. 66. 63. 66. 88. 113. 110. 113. + 117. 118. 113. 103. 91. 84. 70. 65. 59. 58. 60. 59. 55. 50. 53. 58. + 63. 62. 80. 88. 85. 116. 146. 169. 174. 180. 169. 146. 132. 109. + 104. 119. 137. 152. 165. 175. 179. 177. 180. 183. 177. 187. 175. + 166. 167. 121. 68. 68. 60. 49. 46. 52. 55. 52. 41. 49. 59. 64. 63. + 59. 56. 55. 70. 85. 33. 53. 56. 56. 79. 95. 45. 45. 44. 80. 103. 88. + 127. 92. 41. 24. 66. 110. 112. 71. 29. 45. 74. 76. 116. 51. 64. 110. + 110. 117. 78. 91. 101. 49. 38. 41. 55. 49. 38. 39. 42. 46. 52. 61. + 71. 77. 82. 90. 100. 106. 107. 109. 114. 118. 119. 122. 125. 126. + 126. 126. 127. 129. 132. 130. 128. 126. 127. 129. 132. 134. 133. + 135. 136. 136. 135. 136. 138. 140. 142. 142. 142. 142. 142. 142. + 142. 142. 144. 144. 144. 145. 145. 146. 146. 146. 142. 144. 146. + 144. 141. 140. 141. 143. 145. 144. 144. 145. 146. 147. 148. 149. + 153. 153. 154. 156. 158. 161. 163. 165. 169. 171. 175. 178. 180. + 183. 187. 190. 190. 194. 198. 202. 204. 207. 210. 212. 209. 215. + 206. 215. 212. 170. 70. 74. 81. 90. 96. 96. 99. 106. 109. 107. 112. + 110. 110. 113. 117. 119. 116. 113. 117. 112. 106. 105. 105. 102. 95. + 89. 96. 100. 103. 101. 94. 86. 80. 77. 82. 88. 97. 101. 99. 92. 84. + 79. 76. 76. 74. 69. 70. 80. 99. 115. 111. 118. 121. 114. 106. 98. + 86. 73. 66. 64. 62. 60. 59. 57. 54. 51. 52. 56. 61. 58. 72. 78. 78. + 113. 147. 180. 189. 190. 182. 167. 148. 110. 105. 120. 139. 153. + 166. 176. 180. 178. 179. 183. 180. 191. 179. 159. 140. 85. 58. 64. + 66. 56. 45. 43. 49. 55. 42. 48. 56. 61. 60. 58. 58. 59. 68. 89. 57. + 47. 47. 51. 86. 77. 48. 45. 42. 85. 106. 75. 119. 115. 56. 53. 42. + 98. 122. 86. 65. 27. 54. 96. 102. 82. 44. 75. 96. 121. 106. 75. 66. + 53. 48. 41. 43. 41. 43. 45. 47. 50. 57. 67. 78. 86. 93. 100. 108. + 112. 112. 113. 116. 120. 120. 122. 125. 126. 126. 126. 127. 129. + 131. 130. 129. 128. 128. 130. 132. 133. 133. 134. 136. 136. 135. + 136. 138. 140. 141. 141. 141. 141. 141. 141. 141. 140. 144. 144. + 144. 145. 145. 146. 146. 146. 143. 145. 146. 145. 142. 141. 142. + 144. 145. 145. 145. 145. 146. 147. 148. 149. 152. 153. 154. 156. + 159. 162. 164. 166. 168. 171. 175. 178. 180. 183. 186. 189. 189. + 192. 197. 200. 202. 205. 208. 210. 207. 213. 205. 213. 214. 180. 84. + 72. 83. 91. 97. 98. 102. 110. 115. 114. 112. 113. 115. 118. 120. + 119. 116. 113. 119. 114. 109. 106. 105. 102. 97. 93. 103. 105. 107. + 102. 94. 86. 82. 82. 85. 92. 98. 97. 88. 79. 74. 73. 73. 74. 73. 73. + 77. 88. 105. 117. 119. 119. 114. 107. 102. 96. 82. 68. 61. 61. 60. + 58. 56. 53. 51. 49. 51. 55. 59. 52. 62. 67. 70. 111. 151. 191. 202. + 201. 197. 189. 165. 115. 106. 121. 140. 154. 167. 177. 181. 179. + 181. 182. 181. 190. 182. 159. 126. 72. 58. 59. 60. 58. 51. 44. 45. + 50. 47. 52. 56. 58. 56. 56. 59. 62. 51. 78. 79. 39. 42. 56. 114. 77. + 49. 47. 41. 91. 112. 60. 106. 135. 89. 60. 29. 78. 117. 97. 73. 31. + 23. 87. 88. 109. 61. 42. 77. 93. 116. 69. 47. 60. 45. 40. 43. 45. + 48. 50. 53. 58. 65. 76. 88. 96. 103. 109. 114. 117. 116. 115. 117. + 119. 121. 123. 125. 126. 126. 126. 127. 129. 129. 129. 129. 130. + 130. 131. 131. 131. 133. 134. 136. 136. 135. 135. 137. 139. 139. + 139. 139. 139. 139. 139. 140. 140. 144. 144. 144. 145. 145. 146. + 146. 146. 145. 146. 147. 146. 144. 143. 144. 146. 146. 145. 145. + 146. 146. 148. 149. 150. 152. 152. 154. 156. 159. 162. 165. 167. + 167. 170. 174. 177. 179. 182. 185. 188. 187. 191. 195. 198. 200. + 203. 206. 208. 204. 212. 206. 210. 216. 194. 107. 70. 81. 88. 93. + 96. 100. 106. 111. 111. 112. 116. 120. 122. 121. 118. 116. 115. 118. + 116. 112. 108. 105. 103. 102. 101. 113. 114. 112. 104. 94. 87. 87. + 90. 92. 98. 100. 92. 79. 69. 67. 70. 70. 71. 73. 79. 89. 101. 113. + 120. 127. 119. 107. 98. 94. 89. 75. 61. 56. 58. 59. 58. 54. 52. 53. + 55. 51. 54. 57. 49. 56. 59. 67. 113. 163. 195. 202. 205. 206. 198. + 175. 128. 106. 121. 140. 154. 166. 176. 180. 178. 183. 182. 179. + 184. 182. 166. 135. 97. 70. 54. 45. 50. 58. 56. 47. 41. 55. 57. 59. + 57. 55. 56. 61. 65. 46. 62. 88. 40. 45. 64. 135. 85. 46. 51. 45. 95. + 118. 54. 92. 129. 127. 48. 38. 55. 91. 99. 53. 60. 30. 63. 79. 100. + 95. 38. 74. 70. 110. 91. 71. 80. 38. 36. 44. 44. 47. 51. 58. 66. 76. + 86. 97. 103. 108. 111. 115. 117. 116. 116. 116. 118. 121. 124. 126. + 127. 126. 126. 127. 129. 128. 129. 130. 131. 132. 131. 130. 130. + 132. 134. 136. 136. 135. 135. 136. 137. 139. 139. 139. 139. 140. + 140. 140. 140. 144. 144. 144. 145. 145. 146. 146. 146. 147. 147. + 147. 147. 146. 146. 146. 147. 146. 146. 146. 146. 147. 148. 150. + 150. 151. 152. 154. 156. 160. 163. 166. 168. 166. 169. 173. 176. + 178. 181. 184. 187. 187. 191. 195. 198. 200. 202. 205. 207. 205. + 213. 208. 207. 217. 205. 133. 70. 79. 84. 91. 95. 98. 101. 103. 104. + 113. 117. 122. 122. 119. 117. 117. 118. 115. 115. 113. 110. 107. + 107. 109. 112. 121. 120. 115. 105. 95. 91. 94. 99. 98. 99. 97. 88. + 78. 71. 72. 74. 69. 71. 77. 88. 102. 114. 121. 123. 128. 118. 105. + 94. 87. 78. 66. 55. 53. 57. 59. 58. 55. 57. 64. 71. 50. 52. 56. 49. + 55. 57. 66. 116. 178. 195. 196. 206. 208. 196. 179. 146. 106. 121. + 139. 153. 165. 174. 178. 176. 181. 181. 181. 179. 179. 167. 136. + 116. 74. 56. 42. 45. 56. 58. 51. 43. 57. 59. 60. 59. 58. 61. 67. 73. + 62. 57. 83. 51. 50. 68. 124. 77. 44. 55. 51. 97. 120. 55. 81. 103. + 146. 69. 49. 35. 69. 105. 66. 69. 64. 57. 72. 82. 91. 55. 69. 78. + 104. 108. 96. 112. 63. 39. 37. 32. 45. 52. 63. 74. 84. 93. 101. 105. + 109. 111. 114. 117. 117. 118. 119. 120. 122. 125. 127. 127. 127. + 126. 127. 128. 127. 128. 130. 132. 132. 131. 130. 129. 132. 134. + 136. 137. 135. 134. 135. 136. 139. 139. 140. 140. 141. 141. 142. + 142. 144. 144. 144. 145. 145. 146. 146. 146. 148. 147. 147. 147. + 148. 148. 148. 147. 147. 147. 147. 147. 148. 149. 151. 151. 152. + 153. 155. 157. 160. 163. 166. 168. 165. 168. 171. 174. 176. 179. + 183. 186. 188. 191. 195. 198. 200. 202. 204. 206. 207. 213. 212. + 206. 216. 211. 159. 77. 78. 83. 91. 98. 102. 102. 103. 105. 113. + 117. 120. 120. 117. 116. 119. 122. 112. 113. 113. 112. 112. 114. + 118. 122. 126. 122. 113. 104. 96. 94. 98. 101. 96. 92. 88. 84. 82. + 81. 80. 79. 72. 75. 84. 99. 114. 124. 126. 125. 121. 114. 103. 91. + 78. 66. 57. 52. 51. 54. 57. 57. 59. 66. 78. 88. 49. 50. 54. 50. 57. + 56. 63. 112. 184. 196. 193. 204. 207. 193. 181. 156. 106. 120. 138. + 152. 164. 174. 177. 175. 178. 179. 185. 179. 179. 161. 118. 106. 65. + 62. 53. 45. 45. 50. 53. 51. 53. 56. 60. 61. 62. 67. 74. 80. 72. 53. + 65. 66. 59. 86. 106. 67. 49. 56. 54. 99. 116. 54. 76. 79. 129. 112. + 64. 31. 65. 119. 107. 50. 61. 54. 67. 87. 69. 70. 44. 70. 86. 94. + 84. 122. 109. 62. 45. 36. 52. 59. 70. 81. 90. 97. 102. 106. 111. + 113. 115. 118. 120. 122. 124. 124. 123. 125. 128. 128. 127. 126. + 127. 128. 127. 128. 130. 131. 132. 131. 130. 129. 131. 134. 136. + 137. 135. 134. 134. 134. 139. 139. 140. 140. 141. 142. 142. 142. + 144. 144. 144. 145. 145. 146. 146. 146. 148. 147. 146. 147. 149. + 149. 149. 147. 148. 148. 148. 148. 149. 150. 151. 152. 154. 155. + 156. 158. 160. 163. 165. 166. 164. 167. 170. 173. 175. 178. 182. + 185. 188. 191. 195. 198. 199. 201. 203. 205. 208. 211. 214. 207. + 214. 212. 183. 92. 78. 80. 86. 95. 98. 99. 102. 107. 111. 114. 117. + 119. 120. 121. 122. 124. 114. 114. 115. 117. 120. 124. 127. 129. + 127. 119. 108. 99. 95. 94. 94. 94. 86. 82. 80. 82. 86. 87. 85. 81. + 77. 83. 94. 109. 122. 129. 128. 126. 113. 105. 94. 83. 69. 56. 50. + 50. 48. 51. 56. 61. 67. 77. 90. 99. 49. 47. 51. 49. 57. 53. 56. 103. + 175. 196. 196. 200. 201. 193. 182. 150. 107. 122. 140. 153. 165. + 174. 177. 176. 179. 179. 185. 178. 183. 161. 104. 92. 59. 63. 55. + 41. 40. 51. 55. 48. 53. 57. 62. 64. 65. 67. 73. 77. 73. 55. 47. 82. + 72. 120. 95. 59. 62. 53. 53. 103. 110. 47. 74. 72. 92. 119. 99. 45. + 65. 130. 113. 41. 42. 46. 63. 84. 69. 71. 39. 49. 62. 83. 65. 91. + 122. 83. 72. 53. 68. 72. 79. 86. 92. 97. 103. 107. 113. 113. 115. + 118. 121. 124. 125. 125. 124. 126. 128. 128. 127. 126. 127. 128. + 128. 129. 130. 130. 131. 131. 131. 130. 131. 134. 137. 137. 135. + 134. 133. 133. 137. 137. 138. 139. 140. 141. 141. 142. 144. 144. + 144. 145. 145. 146. 146. 146. 148. 146. 145. 146. 149. 150. 149. + 147. 148. 148. 148. 149. 149. 151. 152. 153. 156. 157. 157. 158. + 160. 162. 164. 165. 163. 166. 169. 172. 174. 177. 181. 184. 186. + 190. 193. 196. 197. 199. 201. 203. 207. 206. 214. 208. 212. 211. + 204. 111. 88. 85. 85. 89. 91. 91. 97. 106. 107. 110. 116. 123. 128. + 129. 126. 124. 121. 120. 120. 123. 129. 133. 133. 132. 126. 115. + 101. 93. 91. 89. 84. 78. 76. 77. 81. 85. 89. 88. 85. 82. 84. 91. + 104. 117. 127. 130. 128. 125. 110. 95. 79. 69. 60. 50. 46. 47. 48. + 53. 61. 70. 81. 90. 98. 102. 48. 45. 48. 48. 56. 49. 49. 95. 162. + 195. 199. 195. 194. 194. 180. 139. 108. 123. 141. 155. 166. 176. + 178. 177. 185. 179. 183. 176. 186. 167. 104. 92. 61. 61. 48. 33. 42. + 62. 57. 35. 57. 61. 65. 66. 64. 64. 67. 69. 79. 67. 44. 96. 82. 143. + 87. 46. 73. 49. 51. 107. 105. 38. 74. 77. 63. 91. 137. 63. 62. 133. + 83. 51. 49. 45. 60. 59. 81. 65. 64. 48. 52. 96. 65. 52. 101. 87. 90. + 59. 81. 83. 86. 89. 92. 97. 104. 108. 113. 113. 114. 116. 120. 122. + 123. 123. 124. 126. 128. 129. 127. 126. 127. 128. 129. 129. 129. + 130. 130. 131. 131. 131. 131. 134. 137. 137. 136. 133. 132. 132. + 135. 136. 137. 137. 138. 139. 140. 140. 144. 144. 144. 145. 145. + 146. 146. 146. 148. 145. 144. 145. 149. 150. 149. 146. 149. 149. + 149. 149. 150. 151. 152. 153. 158. 158. 158. 159. 160. 162. 163. + 164. 162. 165. 169. 172. 174. 177. 181. 183. 185. 188. 192. 194. + 195. 197. 199. 201. 205. 202. 213. 209. 210. 210. 215. 124. 107. 99. + 92. 91. 89. 89. 97. 108. 104. 108. 116. 127. 135. 135. 129. 123. + 128. 125. 124. 128. 135. 138. 136. 132. 126. 112. 96. 89. 88. 85. + 75. 66. 71. 78. 86. 91. 91. 88. 85. 84. 88. 97. 110. 122. 128. 129. + 127. 125. 110. 88. 67. 58. 53. 47. 44. 44. 51. 57. 67. 81. 93. 101. + 104. 104.
+ + 1 + 1 +
d
+ + 0.
+ + 65536 + 1 +
d
+ + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0.
+ + <_ type_id="opencv-matrix"> + 1 + 1 +
d
+ + 0. + <_ type_id="opencv-matrix"> + 1 + 1 +
d
+ + 0.
+ + 1 + 2 +
i
+ + 1 2
+
diff --git a/test/helper.rb b/test/helper.rb new file mode 100755 index 00000000..8051ebc3 --- /dev/null +++ b/test/helper.rb @@ -0,0 +1,167 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'digest/md5' +require 'opencv' +include OpenCV + +class OpenCVTestCase < Test::Unit::TestCase + SAMPLE_DIR = File.expand_path(File.dirname(__FILE__)) + '/samples/' + FILENAME_CAT = SAMPLE_DIR + 'cat.jpg' + FILENAME_LENA256x256 = SAMPLE_DIR + 'lena-256x256.jpg' + FILENAME_LENA32x32 = SAMPLE_DIR + 'lena-32x32.jpg' + FILENAME_LENA_EYES = File.expand_path(File.dirname(__FILE__)) + '/samples/lena-eyes.jpg' + FILENAME_FRUITS = SAMPLE_DIR + 'fruits.jpg' + FILENAME_CONTOURS = File.expand_path(File.dirname(__FILE__)) + '/samples/contours.jpg' + FILENAME_CHESSBOARD = SAMPLE_DIR + 'chessboard.jpg' + FILENAME_LINES = SAMPLE_DIR + 'lines.jpg' + HAARCASCADE_FRONTALFACE_ALT = SAMPLE_DIR + 'haarcascade_frontalface_alt.xml.gz' + AVI_SAMPLE = SAMPLE_DIR + 'movie_sample.avi' + + DUMMY_OBJ = Digest::MD5.new # dummy object for argument type check test + + def snap(*images) + n = -1 + images.map! { |val| + n += 1 + if val.is_a? Hash + val + elsif val.is_a? Array + {:title => val[0], :image => val[1] } + else + {:title => "snap-#{n}", :image => val } + end + } + + pos = CvPoint.new(0, 0) + images.each { |img| + w = GUI::Window.new(img[:title]) + w.show(img[:image]) + w.move(pos) + pos.x += img[:image].width + if pos.x > 800 + pos.y += img[:image].height + pos.x = 0 + end + } + + GUI::wait_key + GUI::Window::destroy_all + end + + def hash_img(img) + # Compute a hash for an image, useful for image comparisons + Digest::MD5.hexdigest(img.data) + end + + unless Test::Unit::TestCase.instance_methods.map {|m| m.to_sym }.include? :assert_false + def assert_false(actual, message = nil) + assert_equal(false, actual, message) + end + end + + alias original_assert_in_delta assert_in_delta + + def assert_cvscalar_equal(expected, actual, message = nil) + assert_equal(CvScalar, actual.class, message) + assert_array_equal(expected.to_ary, actual.to_ary, message) + end + + def assert_array_equal(expected, actual, message = nil) + assert_equal(expected.size, actual.size, message) + expected.zip(actual) { |e, a| + assert_equal(e, a, message) + } + end + + def assert_in_delta(expected, actual, delta) + if expected.is_a? CvScalar or actual.is_a? CvScalar + expected = expected.to_ary if expected.is_a? CvScalar + actual = actual.to_ary if actual.is_a? CvScalar + assert_in_delta(expected, actual ,delta) + elsif expected.is_a? Array and actual.is_a? Array + assert_equal(expected.size, actual.size) + expected.zip(actual) { |e, a| + original_assert_in_delta(e, a, delta) + } + else + original_assert_in_delta(expected, actual, delta) + end + end + + def create_cvmat(height, width, depth = :cv8u, channel = 4, &block) + m = CvMat.new(height, width, depth, channel) + block = lambda { |j, i, c| CvScalar.new(*([c + 1] * channel)) } unless block_given? + count = 0 + height.times { |j| + width.times { |i| + m[j, i] = block.call(j, i, count) + count += 1 + } + } + m + end + + def create_iplimage(width, height, depth = :cv8u, channel = 4, &block) + m = IplImage.new(width, height, depth, channel) + block = lambda { |j, i, c| CvScalar.new(*([c + 1] * channel)) } unless block_given? + count = 0 + height.times { |j| + width.times { |i| + m[j, i] = block.call(j, i, count) + count += 1 + } + } + m + end + + def assert_each_cvscalar(actual, delta = 0, &block) + raise unless block_given? + count = 0 + actual.height.times { |j| + actual.width.times { |i| + expected = block.call(j, i, count) + if delta == 0 + expected = expected.to_ary if expected.is_a? CvScalar + assert_array_equal(expected, actual[j, i].to_ary) + else + assert_in_delta(expected, actual[j, i], delta) + end + count += 1 + } + } + end + + def print_cvmat(mat) + s = [] + mat.height.times { |j| + a = [] + mat.width.times { |i| + tmp = mat[j, i].to_ary.map {|m| m.to_f.round(2) }.join(',') + a << "[#{tmp}]" + } + s << a.join(' ') + } + puts s.join("\n") + end + + def count_threshold(mat, threshold, &block) + n = 0 + block = lambda { |a, b| a > b } unless block_given? + (mat.rows * mat.cols).times { |i| + n += 1 if block.call(mat[i][0], threshold) + } + n + end + + def color_hists(mat) + hists = [0] * mat.channel + (mat.rows * mat.cols).times { |i| + hists.size.times { |c| + hists[c] += mat[i][c] + } + } + hists + end +end + diff --git a/test/lbph_save.xml b/test/lbph_save.xml new file mode 100644 index 00000000..b75178b2 --- /dev/null +++ b/test/lbph_save.xml @@ -0,0 +1,4304 @@ + + +1 +8 +8 +8 + + <_ type_id="opencv-matrix"> + 1 + 16384 +
f
+ + 4.16233111e-03 1.35275759e-02 0. 6.24349667e-03 5.20291366e-03 + 1.04058278e-03 3.12174833e-03 1.04058273e-02 0. 0. 0. 0. + 1.04058278e-03 0. 1.14464108e-02 5.41103035e-02 1.04058273e-02 + 1.45681594e-02 0. 1.04058278e-03 2.08116556e-03 0. 0. + 4.16233111e-03 2.08116556e-03 0. 0. 0. 2.91363187e-02 + 2.08116556e-03 1.34235173e-01 1.07180029e-01 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 0. 0. 0. 4.16233111e-03 0. 0. 0. 2.70551518e-02 0. 3.43392305e-02 + 7.28407968e-03 3.12174833e-03 2.08116556e-03 0. 3.12174833e-03 + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.14464108e-02 3.12174833e-03 0. 0. 1.04058278e-03 0. + 1.04058278e-03 0. 7.28407968e-03 0. 0. 0. 3.12174838e-02 + 1.04058278e-03 5.20291366e-03 6.24349667e-03 0. 3.12174833e-03 0. + 2.08116556e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 7.28407968e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 2.91363187e-02 0. 1.35275759e-02 0. 2.08116556e-03 0. + 1.35275759e-02 0. 0. 0. 0. 0. 0. 0. 8.32466222e-03 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. + 0. 0. 0. 0. 6.24349667e-03 3.12174833e-03 8.01248774e-02 0. + 2.70551518e-02 0. 0. 0. 1.45681594e-02 0. 1.04058278e-03 0. 0. 0. + 0. 0. 5.20291366e-03 1.24869933e-02 5.20291403e-02 0. + 1.04058273e-02 1.04058278e-03 0. 0. 1.87304895e-02 8.32466222e-03 + 4.16233111e-03 0. 2.08116556e-03 1.04058273e-02 1.14464108e-02 + 3.12174833e-03 6.03538007e-02 2.08116556e-03 3.12174833e-03 0. 0. + 8.32466222e-03 0. 0. 5.20291366e-03 0. 0. 0. 0. 2.08116556e-03 0. + 5.20291366e-03 1.24869933e-02 1.24869933e-02 8.32466222e-03 + 1.04058278e-03 0. 0. 0. 0. 2.08116556e-03 2.08116556e-03 + 1.04058278e-03 0. 0. 1.14464108e-02 0. 2.49739867e-02 + 2.49739867e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 5.20291366e-03 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. + 0. 0. 9.36524477e-03 1.04058278e-03 8.32466222e-03 7.28407968e-03 + 9.36524477e-03 0. 0. 1.04058278e-03 3.12174833e-03 0. + 1.04058278e-03 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 0. + 0. 1.04058278e-03 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 4.26638946e-02 5.20291366e-03 0. 0. + 3.12174833e-03 0. 0. 2.08116556e-03 1.66493244e-02 1.04058278e-03 + 0. 0. 4.47450578e-02 0. 1.24869933e-02 8.32466222e-03 0. + 2.08116556e-03 0. 0. 0. 0. 0. 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. + 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 3.12174833e-03 1.66493244e-02 0. 6.24349667e-03 0. 1.04058278e-03 + 0. 1.45681594e-02 0. 0. 0. 0. 0. 0. 0. 5.20291366e-03 0. + 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 6.24349667e-03 1.97710730e-02 5.93132190e-02 0. + 1.87304895e-02 2.08116556e-03 4.16233111e-03 0. 1.04058273e-02 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 2.08116556e-03 + 5.20291366e-03 8.84495378e-02 1.82101980e-01 0. 1.35275759e-02 + 1.04058278e-03 2.08116556e-03 0. 1.14464108e-02 1.56087419e-02 + 2.18522381e-02 0. 9.36524477e-03 2.49739867e-02 2.08116546e-02 + 1.56087419e-02 6.76378831e-02 1.76899079e-02 1.24869933e-02 + 2.08116556e-03 2.08116556e-03 1.66493244e-02 4.16233111e-03 + 3.12174833e-03 1.14464108e-02 0. 0. 0. 0. 2.08116556e-03 0. + 2.08116556e-03 2.08116556e-03 2.39334032e-02 1.14464108e-02 0. + 1.04058278e-03 3.12174833e-03 0. 0. 4.16233111e-03 1.04058278e-03 + 0. 1.04058278e-03 0. 2.91363187e-02 6.24349667e-03 1.24869933e-02 + 3.43392305e-02 0. 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 0. + 0. 0. 0. 0. 0. 0. 0. 6.24349667e-03 2.08116556e-03 0. 0. + 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. + 1.76899079e-02 0. 5.20291366e-03 1.24869933e-02 9.36524477e-03 + 2.08116556e-03 0. 1.04058278e-03 6.24349667e-03 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 6.24349667e-03 + 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 3.12174833e-03 0. 2.08116556e-03 2.08116556e-03 3.12174833e-03 + 2.08116556e-03 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. + 4.57856432e-02 6.24349667e-03 1.04058278e-03 0. 2.08116556e-03 0. + 2.08116556e-03 2.08116556e-03 7.28407968e-03 0. 0. 0. + 4.78668064e-02 4.16233111e-03 1.04058273e-02 2.08116546e-02 0. 0. + 1.04058278e-03 2.08116556e-03 0. 0. 0. 4.16233111e-03 0. 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 2.08116556e-03 + 0. 1.14464108e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 1.04058278e-03 9.36524477e-03 3.12174833e-03 + 2.39334032e-02 0. 1.24869933e-02 1.04058278e-03 1.04058278e-03 0. + 1.35275759e-02 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 0. + 3.12174833e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 0. 0. 2.08116556e-03 3.12174833e-03 0. + 8.32466222e-03 4.16233111e-03 1.24869933e-02 0. 6.24349667e-03 + 1.04058278e-03 0. 1.04058278e-03 3.12174833e-03 0. 1.04058278e-03 + 0. 0. 1.04058278e-03 0. 0. 6.24349667e-03 2.39334032e-02 + 6.24349676e-02 0. 1.35275759e-02 3.12174833e-03 2.08116556e-03 0. + 1.35275759e-02 2.18522381e-02 1.66493244e-02 0. 8.32466222e-03 + 1.45681594e-02 5.41103035e-02 9.36524477e-03 1.49843916e-01 + 2.70551518e-02 8.32466222e-03 1.04058278e-03 3.12174833e-03 + 1.45681594e-02 3.12174833e-03 3.12174833e-03 1.66493244e-02 + 1.04058278e-03 0. 0. 0. 3.12174833e-03 0. 1.04058278e-03 + 9.36524477e-03 9.36524477e-03 5.20291366e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 1.04058278e-03 4.16233111e-03 0. 0. 0. + 1.87304895e-02 4.16233111e-03 1.87304895e-02 3.74609791e-02 + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. 1.04058273e-02 1.04058278e-03 + 0. 1.04058278e-03 3.01769003e-02 2.08116556e-03 1.24869933e-02 + 6.24349667e-03 1.76899079e-02 0. 0. 0. 8.32466222e-03 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 2.08116556e-03 1.04058278e-03 1.04058278e-03 1.04058278e-03 + 7.28407968e-03 1.04058278e-03 0. 0. 2.08116556e-03 0. 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 3.01769003e-02 + 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 4.16233093e-02 2.08116556e-03 0. 0. 5.41103035e-02 1.04058278e-03 + 1.87304895e-02 9.36524477e-03 1.04058278e-03 8.32466222e-03 0. + 3.12174833e-03 0. 2.08116556e-03 0. 3.43392305e-02 0. 0. 0. 0. + 1.04058278e-03 0. 0. 8.32466222e-03 0. 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 1.35275759e-02 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 1.56087419e-02 1.04058273e-02 + 2.08116546e-02 0. 2.08116546e-02 1.04058278e-03 2.08116556e-03 0. + 2.08116546e-02 0. 0. 0. 0. 1.04058278e-03 0. 0. 2.08116556e-03 + 2.08116556e-03 3.12174833e-03 0. 1.04058278e-03 0. 0. 0. + 3.12174833e-03 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. + 1.66493244e-02 8.32466222e-03 1.45681594e-02 2.08116556e-03 + 3.12174833e-03 0. 0. 0. 1.04058273e-02 0. 1.04058278e-03 0. 0. 0. + 0. 0. 1.04058278e-03 1.87304895e-02 3.22580673e-02 1.04058278e-03 + 1.45681594e-02 1.04058278e-03 1.04058278e-03 0. 7.28407968e-03 + 2.28928216e-02 1.35275759e-02 0. 1.87304895e-02 3.12174838e-02 + 1.97710730e-02 1.04058273e-02 8.74089524e-02 2.18522381e-02 + 5.20291366e-03 0. 1.04058278e-03 1.35275759e-02 1.04058278e-03 + 2.08116556e-03 2.49739867e-02 0. 0. 0. 0. 3.12174833e-03 + 2.08116556e-03 5.20291366e-03 2.08116546e-02 1.45681594e-02 + 3.12174833e-03 0. 0. 5.20291366e-03 0. 0. 6.24349667e-03 + 4.16233111e-03 0. 0. 0. 4.57856432e-02 3.12174833e-03 + 3.74609791e-02 8.22060406e-02 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 8.32466222e-03 1.04058278e-03 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. + 1.56087419e-02 0. 8.32466222e-03 1.45681594e-02 1.45681594e-02 + 3.12174833e-03 0. 0. 6.24349667e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 + 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 + 5.20291366e-03 0. 2.08116556e-03 4.16233111e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.49739867e-02 2.08116556e-03 + 1.04058278e-03 1.04058278e-03 2.08116556e-03 0. 0. 2.08116556e-03 + 1.97710730e-02 2.08116556e-03 3.12174833e-03 2.08116556e-03 + 5.41103035e-02 4.16233111e-03 1.04058273e-02 2.08116546e-02 0. + 3.12174833e-03 0. 0. 0. 1.04058278e-03 0. 3.64203975e-02 0. 0. 0. + 0. 0. 0. 0. 1.24869933e-02 1.04058278e-03 0. 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.24869933e-02 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 2.08116556e-03 0. 1.04058273e-02 + 2.08116556e-03 1.04058273e-02 0. 3.12174833e-03 1.04058278e-03 + 2.08116556e-03 0. 1.56087419e-02 0. 1.04058278e-03 0. 0. 0. 0. 0. + 3.12174833e-03 0. 4.16233111e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 0. 0. 0. 0. 9.36524477e-03 0. 1.45681594e-02 1.04058278e-03 + 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 5.20291366e-03 3.12174833e-03 + 2.08116546e-02 0. 8.32466222e-03 0. 2.08116556e-03 0. + 6.24349676e-02 1.14464108e-02 6.24349667e-03 2.08116556e-03 + 6.24349667e-03 1.14464108e-02 2.80957352e-02 5.20291366e-03 + 1.17585853e-01 1.04058278e-03 9.36524477e-03 0. 1.04058278e-03 + 6.24349667e-03 1.04058278e-03 0. 1.97710730e-02 0. 0. 0. 0. + 1.04058278e-03 2.08116556e-03 2.08116556e-03 3.95421460e-02 + 1.56087419e-02 7.28407968e-03 0. 2.08116556e-03 0. 0. 0. + 1.04058278e-03 3.12174833e-03 0. 0. 0. 1.76899079e-02 + 2.08116556e-03 3.64203975e-02 7.59625435e-02 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 1.04058273e-02 1.04058278e-03 + 7.28407968e-03 8.32466222e-03 5.20291366e-03 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 0. 0. 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 3.53798158e-02 + 3.12174833e-03 0. 0. 0. 0. 0. 1.04058278e-03 1.87304895e-02 0. 0. + 0. 2.60145701e-02 2.08116556e-03 7.28407968e-03 1.56087419e-02 0. + 0. 0. 0. 0. 0. 0. 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. + 1.97710730e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.35275759e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 6.24349667e-03 0. + 9.36524477e-03 0. 1.04058278e-03 0. 2.80957352e-02 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.14464108e-02 0. 3.12174833e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. + 6.24349667e-03 7.28407968e-03 3.32986489e-02 0. 3.12174833e-03 0. + 1.04058278e-03 0. 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. + 5.20291366e-03 1.73777327e-01 9.15712863e-02 0. 6.24349667e-03 + 1.04058278e-03 0. 0. 1.35275759e-02 3.12174838e-02 9.36524477e-03 + 0. 0. 7.28407968e-03 1.45681594e-02 1.04058273e-02 6.97190464e-02 + 2.08116546e-02 1.04058273e-02 1.04058278e-03 1.04058278e-03 + 1.35275759e-02 3.12174833e-03 0. 2.80957352e-02 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 6.03538007e-02 + 1.97710730e-02 8.32466222e-03 0. 0. 1.04058278e-03 1.04058278e-03 + 0. 1.04058278e-03 6.24349667e-03 2.08116556e-03 0. 0. + 3.85015644e-02 4.16233111e-03 1.66493244e-02 3.95421460e-02 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 4.16233111e-03 0. 0. 0. 0. 0. 0. + 0. 0. 7.28407968e-03 0. 0. 0. 1.04058278e-03 0. 0. 2.08116556e-03 + 4.16233111e-03 0. 0. 0. 2.80957352e-02 4.16233111e-03 + 2.18522381e-02 1.87304895e-02 4.16233111e-03 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 3.12174833e-03 0. 0. 1.04058278e-03 2.08116556e-03 2.08116556e-03 + 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 3.43392305e-02 1.04058278e-03 1.04058278e-03 2.08116556e-03 + 3.12174833e-03 0. 1.04058278e-03 2.08116556e-03 1.14464108e-02 0. + 0. 0. 3.01769003e-02 0. 2.08116546e-02 1.14464108e-02 0. + 2.08116556e-03 0. 1.04058278e-03 0. 1.04058278e-03 0. + 8.32466222e-03 0. 0. 0. 0. 0. 4.16233111e-03 0. 1.66493244e-02 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 1.24869933e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 2.08116556e-03 1.14464108e-02 0. 3.12174833e-03 0. 0. 0. + 1.66493244e-02 0. 0. 0. 0. 0. 1.04058278e-03 0. 6.24349667e-03 + 1.04058278e-03 3.12174833e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. + 0. 0. 2.08116556e-03 3.12174833e-03 0. 1.04058273e-02 + 5.20291366e-03 1.04058273e-02 0. 0. 0. 1.04058278e-03 0. + 9.36524477e-03 0. 0. 0. 0. 0. 0. 0. 4.16233111e-03 1.11342356e-01 + 1.14464108e-02 0. 3.12174833e-03 1.04058278e-03 1.04058278e-03 + 3.12174833e-03 1.76899079e-02 2.08116546e-02 9.36524477e-03 0. + 4.16233111e-03 2.70551518e-02 9.36524477e-03 1.35275759e-02 + 1.14464104e-01 3.22580673e-02 7.28407968e-03 2.08116556e-03 + 6.24349667e-03 1.14464108e-02 0. 4.16233111e-03 1.35275759e-02 + 1.04058278e-03 0. 0. 0. 2.08116556e-03 1.04058278e-03 + 4.16233111e-03 4.37044762e-02 1.14464108e-02 4.16233111e-03 0. 0. + 2.08116556e-03 0. 1.04058278e-03 2.08116556e-03 3.12174833e-03 + 1.04058278e-03 0. 0. 3.22580673e-02 1.04058278e-03 3.01769003e-02 + 1.76899079e-02 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 4.16233111e-03 + 2.08116556e-03 1.04058278e-03 0. 1.04058278e-03 0. 1.04058278e-03 + 0. 3.12174833e-03 1.04058278e-03 0. 0. 1.87304895e-02 + 2.08116556e-03 3.74609791e-02 8.32466222e-03 1.56087419e-02 + 4.16233111e-03 1.04058278e-03 2.08116556e-03 3.12174833e-03 0. 0. + 3.12174833e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 + 0. 5.20291366e-03 3.12174833e-03 0. 2.08116556e-03 1.04058278e-03 + 0. 0. 3.12174833e-03 0. 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 3.74609791e-02 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 4.16233111e-03 0. 0. 0. 1.35275759e-02 0. 0. 0. + 1.66493244e-02 0. 4.16233111e-03 5.20291366e-03 2.08116556e-03 + 6.24349667e-03 0. 1.04058278e-03 0. 2.08116556e-03 0. + 1.04058273e-02 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 6.24349667e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. + 3.12174833e-03 0. 0. 0. 0. 2.08116556e-03 0. 0. 1.14464108e-02 0. + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. + 3.12174833e-03 7.28407968e-03 3.85015644e-02 0. 2.28928216e-02 0. + 2.08116556e-03 0. 1.97710730e-02 1.04058278e-03 1.04058278e-03 0. + 0. 0. 3.12174833e-03 0. 9.36524477e-03 1.04058278e-03 + 1.04058278e-03 0. 2.08116556e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. 0. 6.24349667e-03 + 9.36524477e-03 1.35275759e-02 0. 1.56087419e-02 0. 0. + 2.08116556e-03 9.36524477e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 8.32466222e-03 4.26638946e-02 5.93132190e-02 1.04058278e-03 + 1.87304895e-02 3.12174833e-03 0. 1.04058278e-03 1.45681594e-02 + 1.97710730e-02 1.35275759e-02 0. 1.04058273e-02 1.04058273e-02 + 1.56087419e-02 4.16233111e-03 9.67741981e-02 6.24349667e-03 + 1.35275759e-02 0. 4.16233111e-03 4.16233111e-03 1.04058278e-03 + 1.04058278e-03 1.45681594e-02 0. 0. 0. 0. 1.04058278e-03 0. + 1.76899079e-02 6.03538007e-02 1.04058273e-02 8.32466222e-03 0. + 2.08116556e-03 2.08116556e-03 0. 0. 3.12174833e-03 3.12174833e-03 + 0. 1.04058278e-03 1.04058278e-03 2.49739867e-02 5.20291366e-03 + 1.59209162e-01 1.03017695e-01 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 2.08116556e-03 0. 0. 0. 0. 2.08116556e-03 0. 4.16233111e-03 + 6.24349667e-03 0. 2.08116556e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 1.56087419e-02 2.08116556e-03 0. 0. 0. 0. 0. + 1.04058278e-03 3.12174833e-03 0. 0. 0. 4.16233111e-03 0. + 4.16233111e-03 5.20291366e-03 0. 3.12174833e-03 0. 0. 0. 0. 0. + 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 0. 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 1.04058278e-03 0. 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.14464108e-02 0. 8.32466222e-03 0. + 0. 1.04058278e-03 1.45681594e-02 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.14464108e-02 0. 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.24869933e-02 1.35275759e-02 4.37044762e-02 0. + 5.20291366e-03 0. 1.04058278e-03 0. 1.45681594e-02 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 1.04058273e-02 7.59625435e-02 + 1.44641012e-01 0. 3.12174833e-03 0. 0. 0. 5.20291366e-03 + 2.08116556e-03 3.12174833e-03 0. 0. 2.08116556e-03 9.36524477e-03 + 1.04058273e-02 5.82726374e-02 1.35275759e-02 8.32466222e-03 0. 0. + 3.12174833e-03 1.04058278e-03 0. 4.16233111e-03 0. 0. 0. 0. 0. + 1.04058278e-03 6.24349667e-03 1.76899079e-02 1.14464108e-02 + 4.16233111e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. + 0. 1.14464108e-02 2.08116556e-03 2.18522381e-02 1.76899079e-02 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 0. 1.04058278e-03 + 1.04058278e-03 1.45681594e-02 2.08116556e-03 0. 0. 3.12174833e-03 + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 6.24349667e-03 + 2.08116556e-03 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 4.05827276e-02 0. 1.04058278e-03 + 0. 2.08116556e-03 0. 2.08116556e-03 1.04058278e-03 1.56087419e-02 + 1.04058278e-03 0. 0. 2.08116546e-02 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. + 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. 6.24349667e-03 2.08116556e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 3.12174833e-03 3.12174833e-03 3.22580673e-02 0. 1.76899079e-02 0. + 3.12174833e-03 1.04058278e-03 2.39334032e-02 0. 0. 0. 0. 0. + 2.08116556e-03 0. 2.08116556e-03 1.04058278e-03 0. 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 1.56087419e-02 + 6.76378831e-02 0. 2.08116546e-02 0. 2.08116556e-03 1.04058278e-03 + 1.14464108e-02 0. 0. 0. 0. 1.04058278e-03 0. 2.08116556e-03 + 1.87304895e-02 8.32466185e-02 1.71696156e-01 0. 1.14464108e-02 + 3.12174833e-03 1.04058278e-03 1.04058278e-03 1.76899079e-02 + 2.18522381e-02 2.80957352e-02 0. 7.28407968e-03 1.24869933e-02 + 1.24869933e-02 1.45681594e-02 1.00936532e-01 4.89073917e-02 + 1.87304895e-02 3.12174833e-03 3.12174833e-03 1.04058273e-02 0. + 4.16233111e-03 8.32466222e-03 0. 1.04058278e-03 1.04058278e-03 0. + 1.04058278e-03 0. 3.12174833e-03 3.12174833e-03 1.35275759e-02 + 2.08116556e-03 3.12174833e-03 0. 2.08116556e-03 1.04058278e-03 + 3.12174833e-03 1.04058278e-03 4.16233111e-03 1.04058278e-03 0. 0. + 2.49739867e-02 1.04058278e-03 3.12174838e-02 9.36524477e-03 + 4.16233111e-03 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 1.04058273e-02 0. 1.04058278e-03 1.04058278e-03 4.16233111e-03 0. + 1.04058278e-03 1.04058278e-03 4.16233111e-03 1.04058278e-03 0. + 1.04058278e-03 1.97710730e-02 0. 2.08116546e-02 5.20291366e-03 + 2.28928216e-02 3.12174833e-03 0. 2.08116556e-03 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 3.12174833e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. + 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 7.28407968e-03 + 7.28407968e-03 1.04058278e-03 4.16233111e-03 1.04058278e-03 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 1.87304895e-02 + 3.12174833e-03 0. 2.08116556e-03 2.08116556e-03 0. 1.04058278e-03 + 1.04058278e-03 1.45681594e-02 2.08116556e-03 0. 0. 2.18522381e-02 + 0. 7.28407968e-03 2.08116556e-03 1.04058278e-03 8.32466222e-03 0. + 4.16233111e-03 3.12174833e-03 1.04058278e-03 0. 8.32466222e-03 0. + 0. 0. 1.04058278e-03 0. 0. 0. 3.12174833e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. + 6.24349667e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 0. 0. 7.28407968e-03 9.36524477e-03 4.47450578e-02 + 0. 2.18522381e-02 0. 1.04058278e-03 0. 1.45681594e-02 0. + 1.04058278e-03 0. 1.04058278e-03 2.08116556e-03 2.08116556e-03 0. + 4.16233111e-03 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. + 1.04058278e-03 2.08116556e-03 0. 0. 0. 2.08116556e-03 + 1.04058278e-03 3.12174833e-03 1.04058273e-02 5.09885550e-02 0. + 2.91363187e-02 1.04058278e-03 1.04058278e-03 1.04058278e-03 + 1.45681594e-02 1.04058278e-03 1.04058278e-03 0. 0. 0. + 4.16233111e-03 1.04058278e-03 1.24869933e-02 2.28928216e-02 + 4.37044762e-02 0. 1.76899079e-02 1.04058278e-03 2.08116556e-03 0. + 2.08116556e-03 1.35275759e-02 1.87304895e-02 1.04058278e-03 + 1.66493244e-02 2.18522381e-02 1.35275759e-02 1.87304895e-02 + 9.15712863e-02 5.30697219e-02 1.14464108e-02 0. 4.16233111e-03 + 8.32466222e-03 3.12174833e-03 2.08116556e-03 4.16233111e-03 + 3.12174833e-03 0. 0. 0. 3.12174833e-03 0. 1.04058278e-03 + 2.08116556e-03 8.32466222e-03 1.04058278e-03 0. 0. 6.24349667e-03 + 0. 0. 0. 4.16233111e-03 0. 0. 0. 1.97710730e-02 1.04058278e-03 + 1.24869933e-02 8.32466222e-03 7.28407968e-03 1.04058278e-03 0. 0. + 1.04058278e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 0. 1.14464108e-02 2.08116556e-03 0. 0. 5.20291366e-03 0. + 1.04058278e-03 0. 7.28407968e-03 0. 0. 0. 3.95421460e-02 0. + 1.35275759e-02 5.20291366e-03 2.28928216e-02 2.08116556e-03 + 1.04058278e-03 4.16233111e-03 4.16233111e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. + 0. 0. 0. 2.08116556e-03 0. 0. 0. 2.08116556e-03 0. 1.04058278e-03 + 0. 2.80957352e-02 2.08116556e-03 0. 2.08116556e-03 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 3.12174833e-03 + 0. 2.91363187e-02 1.04058278e-03 3.12174833e-03 0. 4.16233111e-03 + 0. 1.04058278e-03 1.04058278e-03 2.08116546e-02 0. 0. 0. + 1.87304895e-02 0. 9.36524477e-03 7.28407968e-03 4.16233111e-03 + 2.08116556e-03 0. 2.08116556e-03 2.08116556e-03 0. 0. + 1.04058273e-02 0. 0. 0. 0. 1.04058278e-03 2.08116556e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 3.12174833e-03 2.08116556e-03 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 2.08116556e-03 0. 1.04058278e-03 0. 1.04058278e-03 + 0. 0. 4.16233111e-03 1.04058278e-03 1.04058278e-03 7.28407968e-03 + 2.18522381e-02 3.32986489e-02 0. 3.85015644e-02 2.08116556e-03 0. + 0. 1.04058273e-02 0. 0. 0. 3.12174833e-03 0. 0. 0. 3.12174833e-03 + 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 3.12174833e-03 2.08116556e-03 + 0. 1.04058278e-03 0. 1.04058278e-03 0. 2.08116556e-03 + 1.24869933e-02 2.60145701e-02 1.04058278e-03 3.01769003e-02 0. 0. + 1.04058278e-03 7.28407968e-03 0. 0. 0. 3.12174833e-03 0. 0. 0. + 6.24349667e-03 2.28928216e-02 3.74609791e-02 2.08116556e-03 + 1.97710730e-02 3.12174833e-03 2.08116556e-03 2.08116556e-03 + 7.28407968e-03 1.97710730e-02 3.64203975e-02 0. 2.18522381e-02 + 1.66493244e-02 1.66493244e-02 7.28407968e-03 8.74089524e-02 + 4.47450578e-02 5.20291366e-03 1.04058278e-03 4.16233111e-03 + 1.45681594e-02 1.04058278e-03 4.16233111e-03 9.36524477e-03 + 1.04058278e-03 1.04058278e-03 0. 0. 4.16233111e-03 0. 0. + 1.66493244e-02 1.87304895e-02 4.16233111e-03 0. 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 4.16233111e-03 0. 0. 0. 2.39334032e-02 0. + 2.08116556e-03 1.04058278e-03 1.04058278e-03 0. 2.08116556e-03 0. + 5.20291366e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.35275759e-02 0. 0. 0. 5.20291366e-03 0. 0. 0. 2.08116556e-03 0. + 0. 0. 5.93132190e-02 0. 8.32466222e-03 7.28407968e-03 + 2.91363187e-02 0. 2.08116556e-03 2.08116556e-03 6.24349667e-03 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 3.12174833e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. + 2.08116556e-03 0. 0. 0. 3.12174833e-03 0. 0. 0. 1.76899079e-02 0. + 0. 1.04058278e-03 4.16233111e-03 0. 0. 1.04058278e-03 0. + 1.04058278e-03 0. 0. 2.08116556e-03 0. 0. 0. 3.64203975e-02 + 2.08116556e-03 1.04058278e-03 1.04058278e-03 4.16233111e-03 + 1.04058278e-03 2.08116556e-03 1.04058278e-03 2.70551518e-02 + 1.04058278e-03 1.04058278e-03 0. 6.13943823e-02 2.08116556e-03 + 9.36524477e-03 5.20291366e-03 1.04058278e-03 2.08116556e-03 0. + 2.08116556e-03 0. 1.04058278e-03 0. 2.08116546e-02 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 9.36524477e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 2.08116556e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 0. 1.04058278e-03 5.20291366e-03 3.12174833e-03 3.12174833e-03 + 1.56087419e-02 6.24349667e-03 2.39334032e-02 0. 4.68262248e-02 + 1.04058278e-03 2.08116556e-03 0. 1.76899079e-02 0. 0. 0. + 3.12174833e-03 1.04058278e-03 2.08116556e-03 0. 5.20291366e-03 + 2.08116556e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 0. 4.16233111e-03 1.04058278e-03 2.08116556e-03 0. + 5.20291366e-03 1.04058278e-03 2.28928216e-02 2.08116556e-03 + 1.45681594e-02 1.04058278e-03 1.04058278e-03 0. 6.24349667e-03 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 3.12174833e-03 + 3.12174833e-03 1.66493244e-02 0. 5.20291366e-03 2.08116556e-03 + 1.04058278e-03 0. 2.08116556e-03 1.56087419e-02 1.45681594e-02 + 4.16233111e-03 3.01769003e-02 1.97710730e-02 1.56087419e-02 + 5.20291366e-03 1.01977110e-01 1.76899079e-02 7.28407968e-03 0. + 4.16233111e-03 7.28407968e-03 3.12174833e-03 1.04058278e-03 + 2.28928216e-02 0. 1.04058278e-03 0. 0. 3.12174833e-03 0. + 1.76899079e-02 7.59625435e-02 1.14464108e-02 1.87304895e-02 0. + 1.04058278e-03 2.08116556e-03 2.08116556e-03 0. 1.04058278e-03 + 3.12174833e-03 1.04058278e-03 0. 0. 1.66493244e-02 1.04058278e-03 + 6.24349676e-02 8.42872038e-02 1.04058278e-03 2.08116556e-03 0. 0. + 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 4.16233111e-03 0. + 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 5.20291366e-03 + 1.04058278e-03 0. 1.04058278e-03 1.45681594e-02 1.04058278e-03 + 1.66493244e-02 7.28407968e-03 6.24349667e-03 1.04058278e-03 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 4.16233111e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 6.24349667e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. + 2.08116546e-02 1.04058278e-03 1.04058278e-03 0. 2.08116556e-03 + 1.04058278e-03 0. 1.04058278e-03 2.18522381e-02 0. 1.04058278e-03 + 1.04058278e-03 3.22580673e-02 0. 9.36524477e-03 1.04058278e-03 0. + 0. 0. 3.12174833e-03 0. 0. 0. 9.36524477e-03 0. 0. 0. 0. 0. 0. 0. + 7.28407968e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 4.16233111e-03 + 1.04058278e-03 1.24869933e-02 0. 3.12174833e-03 0. 0. 0. + 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 2.39334032e-02 3.12174838e-02 0. 3.12174833e-03 1.04058278e-03 0. + 0. 1.04058278e-03 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. + 1.14464108e-02 8.42872038e-02 9.36524495e-02 4.16233111e-03 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 1.04058278e-03 + 1.56087419e-02 1.24869933e-02 1.04058278e-03 4.16233111e-03 + 1.76899079e-02 8.32466222e-03 1.24869933e-02 6.34755492e-02 + 3.74609791e-02 1.14464108e-02 1.04058278e-03 8.32466222e-03 + 1.04058273e-02 4.16233111e-03 4.16233111e-03 1.56087419e-02 + 1.04058278e-03 2.08116556e-03 0. 0. 5.20291366e-03 3.12174833e-03 + 2.08116556e-03 3.32986489e-02 1.66493244e-02 4.16233111e-03 + 1.04058278e-03 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 5.20291366e-03 1.04058278e-03 0. 1.04058278e-03 1.66493244e-02 + 1.04058278e-03 3.43392305e-02 2.70551518e-02 1.04058278e-03 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 2.08116556e-03 4.16233111e-03 0. + 0. 0. 0. 1.04058278e-03 0. 0. 2.08116556e-03 0. 0. 0. + 4.16233111e-03 1.04058278e-03 6.24349667e-03 5.20291366e-03 + 1.24869933e-02 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 0. 3.12174833e-03 0. 2.08116556e-03 2.08116556e-03 + 6.24349667e-03 4.16233111e-03 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 4.05827276e-02 0. 0. 0. 4.16233111e-03 0. + 1.04058278e-03 1.04058278e-03 9.36524477e-03 0. 0. 0. + 6.24349667e-03 0. 3.12174833e-03 5.20291366e-03 3.12174833e-03 + 5.20291366e-03 0. 5.20291366e-03 0. 0. 0. 1.24869933e-02 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 9.36524477e-03 0. 0. 0. + 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 2.08116556e-03 2.08116556e-03 0. 9.36524477e-03 1.04058278e-03 0. + 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 4.16233111e-03 1.04058278e-03 0. 4.16233111e-03 + 3.12174833e-03 3.32986489e-02 0. 2.60145701e-02 0. 0. 0. + 2.08116546e-02 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. + 1.45681594e-02 3.12174833e-03 1.14464108e-02 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 0. 2.08116556e-03 + 0. 0. 1.04058273e-02 1.04058278e-03 2.08116546e-02 0. + 2.18522381e-02 1.04058278e-03 1.04058278e-03 2.08116556e-03 + 1.14464108e-02 1.04058278e-03 1.04058278e-03 0. 2.08116556e-03 0. + 0. 2.08116556e-03 1.04058273e-02 7.59625435e-02 3.74609791e-02 0. + 1.04058273e-02 1.04058278e-03 0. 1.04058278e-03 3.74609791e-02 + 2.60145701e-02 1.14464108e-02 1.04058278e-03 7.28407968e-03 + 7.28407968e-03 4.16233111e-03 9.36524477e-03 9.78147835e-02 + 5.51508889e-02 1.87304895e-02 2.08116556e-03 5.20291366e-03 + 1.35275759e-02 1.04058278e-03 3.12174833e-03 7.28407968e-03 0. + 1.04058278e-03 0. 0. 2.08116556e-03 0. 6.24349667e-03 + 4.16233111e-03 1.66493244e-02 0. 1.04058278e-03 0. 8.32466222e-03 + 0. 4.16233111e-03 1.04058278e-03 1.04058278e-03 0. 0. 0. + 4.57856432e-02 0. 7.18002096e-02 6.24349667e-03 2.08116556e-03 + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 8.32466222e-03 0. 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 2.08116556e-03 + 8.32466222e-03 0. 0. 0. 2.39334032e-02 0. 3.85015644e-02 + 8.32466222e-03 9.36524477e-03 7.28407968e-03 0. 1.04058278e-03 + 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 4.16233111e-03 3.12174833e-03 + 0. 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 2.08116556e-03 + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.14464108e-02 4.16233111e-03 + 1.04058278e-03 2.08116556e-03 0. 0. 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 0. 0. 1.04058278e-03 2.08116556e-03 1.04058278e-03 + 6.24349667e-03 1.04058278e-03 0. 5.20291366e-03 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 5.20291366e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 5.20291366e-03 3.12174833e-03 + 3.12174833e-03 8.32466222e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 1.04058278e-03 7.28407968e-03 5.20291366e-03 + 6.24349676e-02 0. 3.22580673e-02 0. 2.08116556e-03 0. + 3.12174833e-03 0. 2.08116556e-03 0. 1.04058278e-03 0. + 5.20291366e-03 0. 9.36524477e-03 1.04058278e-03 1.04058278e-03 0. + 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 3.12174833e-03 0. 0. + 5.20291366e-03 3.12174833e-03 3.12174833e-03 6.24349667e-03 + 5.20291366e-03 9.36524495e-02 0. 5.61914705e-02 1.04058278e-03 0. + 0. 7.28407968e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. 1.35275759e-02 + 1.66493244e-02 1.56087419e-02 0. 1.14464108e-02 0. 0. 0. + 5.20291366e-03 3.12174833e-03 1.14464108e-02 0. 7.28407968e-03 + 1.04058273e-02 1.04058273e-02 1.45681594e-02 7.18002096e-02 + 6.24349667e-03 9.36524477e-03 0. 4.16233111e-03 1.04058278e-03 + 4.16233111e-03 1.04058278e-03 1.76899079e-02 0. 0. 0. 0. 0. 0. + 9.36524477e-03 7.38813803e-02 5.20291366e-03 8.32466222e-03 0. + 3.12174833e-03 3.12174833e-03 1.04058278e-03 0. 1.24869933e-02 0. + 1.04058278e-03 0. 1.04058278e-03 2.28928216e-02 3.12174833e-03 + 2.49739867e-02 1.12382941e-01 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 4.16233111e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058273e-02 0. 0. 0. + 1.04058278e-03 0. 0. 2.08116556e-03 3.12174833e-03 0. 0. 0. + 2.18522381e-02 3.12174833e-03 2.08116556e-03 1.35275759e-02 0. + 1.04058278e-03 0. 3.12174833e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. + 0. 0. 0. 0. 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 1.04058278e-03 1.87304895e-02 0. 1.97710730e-02 0. 3.12174833e-03 + 0. 2.49739867e-02 0. 0. 0. 0. 0. 0. 0. 8.32466222e-03 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 3.12174833e-03 0. 0. 0. + 0. 0. 3.12174833e-03 0. 8.32466222e-03 3.01769003e-02 + 8.01248774e-02 0. 1.24869933e-02 0. 1.04058278e-03 0. + 9.36524477e-03 0. 0. 0. 0. 0. 0. 0. 4.16233111e-03 4.16233093e-02 + 1.77939653e-01 0. 9.36524477e-03 1.04058278e-03 0. 0. + 1.14464108e-02 2.08116556e-03 3.12174833e-03 0. 1.04058278e-03 + 6.24349667e-03 1.35275759e-02 5.20291366e-03 8.32466185e-02 + 1.76899079e-02 2.49739867e-02 0. 3.12174833e-03 4.16233111e-03 + 2.08116556e-03 0. 5.20291366e-03 0. 1.04058278e-03 0. 0. + 2.08116556e-03 0. 1.04058273e-02 3.74609791e-02 2.39334032e-02 + 1.87304895e-02 3.12174833e-03 0. 1.04058278e-03 0. 0. + 2.08116556e-03 4.16233111e-03 1.04058278e-03 0. 0. 1.76899079e-02 + 4.16233111e-03 3.12174838e-02 5.61914705e-02 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 3.12174833e-03 0. + 5.20291366e-03 9.36524477e-03 7.28407968e-03 1.04058278e-03 0. 0. + 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 8.32466222e-03 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 2.08116556e-03 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 2.39334032e-02 2.08116556e-03 0. 0. + 1.04058278e-03 0. 0. 0. 4.16233111e-03 1.04058278e-03 0. 0. + 1.04058273e-02 0. 1.56087419e-02 1.04058273e-02 2.08116556e-03 0. + 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 4.16233111e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 0. 0. 0. 0. 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 1.04058278e-03 2.18522381e-02 0. + 4.16233111e-03 0. 0. 0. 9.36524477e-03 0. 0. 0. 0. 0. 0. 0. + 1.35275759e-02 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 5.20291366e-03 1.97710730e-02 8.01248774e-02 + 0. 1.45681594e-02 1.04058278e-03 0. 1.04058278e-03 1.04058273e-02 + 0. 0. 0. 0. 0. 0. 4.16233111e-03 1.66493244e-02 4.78668064e-02 + 1.16545275e-01 0. 1.24869933e-02 1.04058278e-03 3.12174833e-03 0. + 1.87304895e-02 1.56087419e-02 1.45681594e-02 0. 5.20291366e-03 + 7.28407968e-03 1.24869933e-02 1.87304895e-02 1.10301778e-01 + 6.45161346e-02 1.04058273e-02 1.04058278e-03 6.24349667e-03 + 1.14464108e-02 0. 1.14464108e-02 2.08116546e-02 2.08116556e-03 0. + 1.04058278e-03 0. 6.24349667e-03 1.04058278e-03 2.28928216e-02 + 6.03538007e-02 1.35275759e-02 0. 1.04058278e-03 2.08116556e-03 + 5.20291366e-03 0. 2.08116556e-03 0. 4.16233111e-03 0. + 2.08116556e-03 1.04058278e-03 2.60145701e-02 2.08116556e-03 + 3.64203975e-02 2.91363187e-02 2.08116556e-03 0. 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.14464108e-02 2.08116556e-03 0. 2.08116556e-03 1.04058278e-03 + 1.04058278e-03 2.08116556e-03 1.04058278e-03 6.24349667e-03 + 1.04058278e-03 0. 0. 2.80957352e-02 0. 2.39334032e-02 + 7.28407968e-03 2.28928216e-02 8.32466222e-03 0. 1.04058278e-03 + 3.12174833e-03 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 1.14464108e-02 2.08116556e-03 + 1.04058278e-03 3.12174833e-03 1.04058278e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058273e-02 2.08116556e-03 + 0. 0. 0. 0. 0. 0. 7.28407968e-03 0. 0. 0. 8.32466222e-03 0. + 1.66493244e-02 2.08116556e-03 1.04058278e-03 3.12174833e-03 0. 0. + 0. 0. 1.04058278e-03 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. + 2.39334032e-02 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 2.08116556e-03 2.08116556e-03 4.16233111e-03 1.56087419e-02 0. 0. + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 + 1.04058278e-03 1.24869933e-02 6.24349667e-03 3.74609791e-02 0. + 1.14464108e-02 0. 0. 0. 8.32466222e-03 0. 5.20291366e-03 0. + 1.04058278e-03 0. 3.12174833e-03 1.04058278e-03 9.36524477e-03 + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 7.28407968e-03 4.16233111e-03 3.74609791e-02 0. + 3.22580673e-02 0. 0. 2.08116556e-03 1.04058273e-02 0. + 1.04058278e-03 0. 3.12174833e-03 0. 1.04058278e-03 1.04058278e-03 + 1.14464108e-02 6.24349667e-03 1.04058273e-02 0. 9.36524477e-03 0. + 0. 0. 2.08116556e-03 8.32466222e-03 1.56087419e-02 0. + 1.35275759e-02 8.32466222e-03 7.28407968e-03 8.32466222e-03 + 7.80437067e-02 8.74089524e-02 1.04058273e-02 2.08116556e-03 + 3.12174833e-03 1.76899079e-02 3.12174833e-03 8.32466222e-03 + 4.16233111e-03 2.08116556e-03 0. 0. 0. 8.32466222e-03 + 2.08116556e-03 8.32466222e-03 1.04058278e-03 2.28928216e-02 0. 0. + 0. 5.20291366e-03 0. 2.08116556e-03 0. 7.28407968e-03 0. 0. 0. + 3.43392305e-02 1.04058278e-03 9.36524477e-03 1.04058278e-03 + 4.16233111e-03 0. 1.04058278e-03 0. 7.28407968e-03 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058273e-02 + 0. 0. 1.04058278e-03 6.24349667e-03 1.04058278e-03 3.12174833e-03 + 1.04058278e-03 9.36524477e-03 1.04058278e-03 0. 1.04058278e-03 + 5.41103035e-02 1.04058278e-03 2.70551518e-02 1.14464108e-02 + 2.08116546e-02 3.12174833e-03 2.08116556e-03 1.04058278e-03 + 1.04058278e-03 0. 1.04058278e-03 0. 2.08116556e-03 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 2.08116556e-03 0. + 0. 1.04058278e-03 0. 0. 0. 0. 3.12174833e-03 0. 0. 0. + 1.04058278e-03 0. 0. 2.08116556e-03 1.14464108e-02 1.04058278e-03 + 1.04058278e-03 4.16233111e-03 1.04058278e-03 0. 0. 1.04058278e-03 + 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 2.18522381e-02 0. + 1.04058278e-03 4.16233111e-03 3.12174833e-03 0. 1.04058278e-03 + 2.08116556e-03 1.76899079e-02 0. 0. 1.04058278e-03 1.87304895e-02 + 3.12174833e-03 8.32466222e-03 9.36524477e-03 5.20291366e-03 + 4.16233111e-03 0. 7.28407968e-03 0. 1.04058278e-03 0. + 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 + 0. 0. 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. + 0. 2.08116556e-03 4.16233111e-03 0. 4.16233111e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 1.04058278e-03 6.24349667e-03 4.16233111e-03 + 4.16233111e-03 2.18522381e-02 1.04058273e-02 2.49739867e-02 + 1.04058278e-03 1.35275759e-02 0. 0. 1.04058278e-03 2.08116556e-03 + 2.08116556e-03 2.08116556e-03 0. 4.16233111e-03 0. 2.08116556e-03 + 0. 6.24349667e-03 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 3.12174833e-03 0. 2.08116556e-03 1.04058278e-03 2.08116556e-03 + 0. 5.20291366e-03 4.16233111e-03 1.87304895e-02 0. 2.70551518e-02 + 0. 0. 0. 1.14464108e-02 0. 1.04058278e-03 0. 2.08116556e-03 + 1.04058278e-03 0. 0. 1.35275759e-02 6.24349667e-03 1.04058273e-02 + 1.04058278e-03 1.24869933e-02 1.04058278e-03 0. 0. 6.24349667e-03 + 1.87304895e-02 1.04058273e-02 1.04058278e-03 1.24869933e-02 + 1.35275759e-02 1.24869933e-02 1.45681594e-02 9.05307010e-02 + 7.70031288e-02 9.36524477e-03 1.04058278e-03 2.08116556e-03 + 3.32986489e-02 6.24349667e-03 4.16233111e-03 7.28407968e-03 + 5.20291366e-03 1.04058278e-03 1.04058278e-03 1.04058278e-03 + 3.12174833e-03 2.08116556e-03 1.04058278e-03 7.28407968e-03 + 1.45681594e-02 3.12174833e-03 0. 0. 5.20291366e-03 0. + 1.04058278e-03 0. 1.45681594e-02 0. 0. 0. 2.39334032e-02 + 3.12174833e-03 4.16233111e-03 7.28407968e-03 4.16233111e-03 + 1.04058278e-03 0. 0. 2.08116556e-03 0. 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 0. 2.08116556e-03 0. 0. 2.08116556e-03 + 1.04058273e-02 0. 0. 0. 4.16233111e-03 0. 2.08116556e-03 + 2.08116556e-03 1.56087419e-02 0. 0. 2.08116556e-03 4.89073917e-02 + 1.04058278e-03 2.39334032e-02 8.32466222e-03 1.97710730e-02 + 1.04058278e-03 0. 2.08116556e-03 4.16233111e-03 0. 2.08116556e-03 + 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 + 0. 0. 2.08116556e-03 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 0. + 0. 0. 0. 0. 1.04058278e-03 1.35275759e-02 1.04058278e-03 0. + 2.08116556e-03 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 3.12174833e-03 0. 1.04058278e-03 0. 3.95421460e-02 0. + 1.04058278e-03 2.08116556e-03 0. 0. 1.04058278e-03 0. + 3.64203975e-02 2.08116556e-03 4.16233111e-03 3.12174833e-03 + 2.08116546e-02 1.04058278e-03 1.45681594e-02 1.56087419e-02 + 3.12174833e-03 3.12174833e-03 0. 3.12174833e-03 0. 2.08116556e-03 + 0. 2.08116556e-03 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 0. 4.16233111e-03 1.04058278e-03 1.04058278e-03 0. + 0. 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 0. 0. 1.04058278e-03 + 4.16233111e-03 0. 6.24349667e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 3.12174833e-03 2.08116556e-03 1.04058278e-03 0. + 1.04058278e-03 5.20291366e-03 3.12174833e-03 2.08116556e-03 + 1.35275759e-02 3.12174833e-03 1.97710730e-02 0. 1.56087419e-02 0. + 0. 0. 6.24349667e-03 1.04058278e-03 1.04058278e-03 0. + 1.04058278e-03 1.04058278e-03 0. 0. 8.32466222e-03 2.08116556e-03 + 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 2.08116556e-03 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 2.08116556e-03 + 4.16233111e-03 7.28407968e-03 0. 2.60145701e-02 0. 0. 0. + 4.16233111e-03 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. + 1.04058278e-03 6.24349667e-03 1.14464108e-02 7.28407968e-03 0. + 7.28407968e-03 1.04058278e-03 0. 0. 3.12174833e-03 1.76899079e-02 + 1.35275759e-02 0. 3.01769003e-02 1.76899079e-02 9.36524477e-03 + 1.87304895e-02 9.36524495e-02 5.61914705e-02 9.36524477e-03 + 3.12174833e-03 2.08116556e-03 1.76899079e-02 2.08116556e-03 + 2.08116556e-03 5.20291366e-03 2.08116556e-03 0. 0. 0. + 2.08116556e-03 1.04058278e-03 2.08116556e-03 1.35275759e-02 + 9.36524477e-03 1.04058278e-03 0. 1.04058278e-03 5.20291366e-03 + 1.04058278e-03 1.04058278e-03 0. 6.24349667e-03 1.04058278e-03 0. + 0. 2.80957352e-02 2.08116556e-03 1.87304895e-02 8.32466222e-03 + 4.16233111e-03 0. 0. 1.04058278e-03 2.08116556e-03 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 7.28407968e-03 + 3.12174833e-03 0. 0. 1.04058273e-02 0. 2.08116556e-03 0. + 7.28407968e-03 0. 0. 0. 5.61914705e-02 2.08116556e-03 + 2.39334032e-02 6.24349667e-03 2.80957352e-02 3.12174833e-03 + 4.16233111e-03 1.04058278e-03 1.04058278e-03 0. 0. 2.08116556e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 2.08116556e-03 0. + 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 2.08116556e-03 0. 0. 0. + 0. 0. 0. 1.04058278e-03 3.12174833e-03 2.08116556e-03 + 2.08116556e-03 1.04058278e-03 2.08116556e-03 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.28928216e-02 0. 0. + 1.04058278e-03 2.08116556e-03 0. 2.08116556e-03 2.08116556e-03 + 1.04058273e-02 0. 0. 0. 3.01769003e-02 1.04058278e-03 + 9.36524477e-03 3.12174833e-03 1.04058278e-03 4.16233111e-03 0. + 2.08116556e-03 0. 0. 0. 7.28407968e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 7.28407968e-03 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 2.08116556e-03 + 1.04058278e-03 1.04058278e-03 8.32466222e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 + 1.04058278e-03 2.08116556e-03 1.45681594e-02 2.08116556e-03 + 3.32986489e-02 0. 8.01248774e-02 0. 1.04058278e-03 0. + 2.28928216e-02 0. 1.04058278e-03 0. 5.20291366e-03 1.04058278e-03 + 1.04058278e-03 0. 4.16233111e-03 3.12174833e-03 5.20291366e-03 0. + 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 3.12174833e-03 + 1.04058278e-03 4.16233111e-03 0. 0. 2.08116556e-03 6.24349667e-03 + 0. 6.24349667e-03 2.08116556e-03 6.24349667e-03 0. 2.08116546e-02 + 1.04058278e-03 1.04058278e-03 0. 8.32466222e-03 1.04058278e-03 + 1.04058278e-03 0. 3.12174833e-03 1.04058278e-03 1.04058278e-03 0. + 5.20291366e-03 1.56087419e-02 1.14464108e-02 1.04058278e-03 + 1.45681594e-02 2.08116556e-03 0. 0. 1.04058273e-02 1.24869933e-02 + 1.04058273e-02 0. 1.87304895e-02 1.56087419e-02 7.28407968e-03 + 7.28407968e-03 9.26118642e-02 6.13943823e-02 2.18522381e-02 + 2.08116556e-03 4.16233111e-03 1.56087419e-02 1.04058278e-03 + 1.04058278e-03 5.20291366e-03 1.04058278e-03 2.08116556e-03 0. 0. + 7.28407968e-03 1.04058278e-03 5.20291366e-03 1.14464108e-02 + 2.70551518e-02 3.12174833e-03 1.04058278e-03 2.08116556e-03 + 5.20291366e-03 0. 0. 1.04058278e-03 7.28407968e-03 1.04058278e-03 + 0. 0. 2.28928216e-02 1.04058278e-03 6.13943823e-02 1.04058273e-02 + 1.04058278e-03 2.08116556e-03 1.04058278e-03 2.08116556e-03 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 5.20291366e-03 1.04058278e-03 0. 0. 3.12174833e-03 0. + 2.08116556e-03 2.08116556e-03 3.12174833e-03 1.04058278e-03 0. 0. + 4.26638946e-02 0. 1.97710730e-02 9.36524477e-03 8.32466222e-03 + 3.12174833e-03 0. 1.04058278e-03 1.04058278e-03 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 2.08116556e-03 0. 5.20291366e-03 + 2.08116556e-03 2.08116556e-03 1.04058278e-03 0. 0. 2.08116556e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 1.24869933e-02 + 4.16233111e-03 1.04058278e-03 5.20291366e-03 2.08116556e-03 0. 0. + 0. 6.24349667e-03 0. 0. 0. 1.14464108e-02 0. 8.32466222e-03 + 4.16233111e-03 3.12174833e-03 3.12174833e-03 0. 4.16233111e-03 0. + 2.08116556e-03 0. 4.16233111e-03 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 9.36524477e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 2.08116556e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 2.08116556e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 3.12174833e-03 1.04058273e-02 1.24869933e-02 + 3.22580673e-02 0. 2.70551518e-02 0. 0. 0. 1.24869933e-02 + 1.04058278e-03 3.12174833e-03 0. 2.08116556e-03 0. 1.04058278e-03 + 1.04058278e-03 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 2.08116556e-03 4.16233111e-03 + 2.08116556e-03 4.16233111e-03 6.24349667e-03 5.51508889e-02 0. + 3.85015644e-02 0. 0. 0. 1.35275759e-02 1.04058278e-03 + 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 + 1.56087419e-02 1.87304895e-02 3.53798158e-02 2.08116556e-03 + 5.20291366e-03 1.04058278e-03 0. 1.04058278e-03 9.36524477e-03 + 1.35275759e-02 1.04058273e-02 0. 1.45681594e-02 9.36524477e-03 + 5.20291366e-03 1.87304895e-02 8.01248774e-02 2.08116546e-02 + 1.56087419e-02 0. 2.08116556e-03 1.56087419e-02 4.16233111e-03 + 6.24349667e-03 2.60145701e-02 0. 0. 0. 0. 5.20291366e-03 0. + 3.12174833e-03 5.20291366e-03 2.08116546e-02 1.14464108e-02 + 1.04058278e-03 3.12174833e-03 1.04058278e-03 0. 3.12174833e-03 + 6.24349667e-03 0. 1.04058278e-03 0. 0. 3.43392305e-02 + 2.08116556e-03 1.66493244e-02 4.78668064e-02 0. 1.04058278e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 0. 2.08116556e-03 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 1.14464108e-02 1.04058278e-03 1.56087419e-02 1.56087419e-02 + 6.24349667e-03 7.28407968e-03 0. 0. 1.04058278e-03 0. + 1.04058278e-03 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. + 2.08116556e-03 1.04058278e-03 2.08116556e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.14464108e-02 + 4.16233111e-03 0. 0. 1.04058278e-03 0. 1.04058278e-03 + 2.08116556e-03 4.16233111e-03 0. 0. 0. 1.45681594e-02 0. + 9.36524477e-03 1.56087419e-02 0. 1.04058278e-03 0. 1.04058278e-03 + 0. 0. 0. 4.16233111e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058273e-02 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 + 1.24869933e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 6.24349667e-03 5.20291366e-03 4.26638946e-02 0. 1.04058273e-02 0. + 1.04058278e-03 0. 1.14464108e-02 0. 2.08116556e-03 0. + 1.04058278e-03 0. 1.04058278e-03 0. 1.35275759e-02 0. 0. 0. 0. 0. + 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 + 3.01769003e-02 5.20291366e-03 1.31113425e-01 0. 2.91363187e-02 + 1.04058278e-03 3.12174833e-03 0. 1.14464108e-02 0. 1.04058278e-03 + 0. 0. 0. 0. 0. 7.28407968e-03 6.24349667e-03 2.39334032e-02 0. + 9.36524477e-03 1.04058278e-03 1.04058278e-03 0. 7.28407968e-03 + 1.04058278e-03 8.32466222e-03 0. 9.36524477e-03 1.14464108e-02 + 1.66493244e-02 6.24349667e-03 1.50884509e-01 4.16233111e-03 + 1.56087419e-02 0. 1.04058278e-03 5.20291366e-03 0. 4.16233111e-03 + 1.45681594e-02 0. 0. 0. 0. 3.12174833e-03 0. 3.12174833e-03 + 6.03538007e-02 1.04058273e-02 2.60145701e-02 1.04058278e-03 0. + 2.08116556e-03 0. 0. 1.24869933e-02 0. 3.12174833e-03 0. + 1.04058278e-03 1.45681594e-02 0. 3.01769003e-02 2.01873064e-01 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 6.24349667e-03 0. 6.24349667e-03 + 1.45681594e-02 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 9.36524477e-03 2.08116556e-03 0. 0. + 2.08116556e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. + 1.24869933e-02 2.08116556e-03 4.16233111e-03 6.24349667e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 5.20291366e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 3.12174833e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 1.24869933e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 8.32466222e-03 0. 1.04058278e-03 0. 0. 0. 9.36524477e-03 0. + 0. 0. 0. 0. 0. 0. 6.24349667e-03 0. 2.08116556e-03 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 1.04058273e-02 7.28407968e-03 4.26638946e-02 0. + 2.08116556e-03 0. 0. 0. 1.14464108e-02 0. 0. 0. 0. 0. 0. + 1.04058278e-03 5.20291366e-03 8.74089524e-02 1.81061402e-01 0. + 4.16233111e-03 0. 1.04058278e-03 0. 1.87304895e-02 3.12174833e-03 + 5.20291366e-03 0. 2.08116556e-03 2.08116556e-03 4.16233111e-03 + 1.04058273e-02 5.72320521e-02 2.80957352e-02 1.76899079e-02 + 1.04058278e-03 4.16233111e-03 3.12174833e-03 1.04058278e-03 + 4.16233111e-03 2.08116546e-02 1.04058278e-03 0. 0. 0. 0. 0. + 7.28407968e-03 2.60145701e-02 1.76899079e-02 1.45681594e-02 + 1.04058278e-03 2.08116556e-03 0. 0. 0. 2.08116556e-03 0. + 2.08116556e-03 0. 0. 1.04058273e-02 1.04058278e-03 2.49739867e-02 + 3.32986489e-02 0. 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 0. + 0. 0. 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. + 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 7.28407968e-03 + 1.04058278e-03 3.12174833e-03 4.16233111e-03 1.45681594e-02 + 1.04058278e-03 0. 1.04058278e-03 7.28407968e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 5.20291366e-03 2.08116556e-03 1.04058278e-03 1.04058278e-03 0. 0. + 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 1.97710730e-02 + 2.08116556e-03 0. 0. 2.08116556e-03 0. 1.04058278e-03 0. + 8.32466222e-03 0. 0. 1.04058278e-03 1.45681594e-02 0. + 2.08116556e-03 3.12174833e-03 0. 2.08116556e-03 0. 4.16233111e-03 + 0. 1.04058278e-03 0. 5.20291366e-03 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 1.14464108e-02 1.04058278e-03 2.08116556e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 + 9.36524477e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 4.16233111e-03 2.08116556e-03 3.74609791e-02 0. + 8.32466222e-03 2.08116556e-03 0. 0. 1.45681594e-02 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 1.35275759e-02 + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 0. 0. 0. 0. 1.04058278e-03 1.14464108e-02 1.56087419e-02 + 7.49219581e-02 0. 2.60145701e-02 1.04058278e-03 3.12174833e-03 0. + 1.45681594e-02 0. 0. 0. 0. 0. 1.04058278e-03 3.12174833e-03 + 3.01769003e-02 5.09885550e-02 1.05098858e-01 1.04058278e-03 + 1.87304895e-02 2.08116556e-03 1.04058278e-03 0. 1.14464108e-02 + 6.24349667e-03 1.87304895e-02 0. 1.35275759e-02 6.24349667e-03 + 1.04058273e-02 1.66493244e-02 8.22060406e-02 7.07596317e-02 + 2.39334032e-02 6.24349667e-03 1.04058273e-02 1.24869933e-02 + 2.08116556e-03 9.36524477e-03 1.14464108e-02 3.12174833e-03 0. 0. + 1.04058278e-03 7.28407968e-03 3.12174833e-03 1.35275759e-02 + 3.01769003e-02 3.32986489e-02 5.20291366e-03 0. 1.04058278e-03 + 3.12174833e-03 0. 5.20291366e-03 1.04058278e-03 6.24349667e-03 + 1.04058278e-03 0. 0. 3.95421460e-02 0. 5.20291403e-02 + 2.49739867e-02 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. + 2.08116556e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 7.28407968e-03 1.04058278e-03 0. 2.08116556e-03 3.12174833e-03 0. + 2.08116556e-03 0. 4.16233111e-03 1.04058278e-03 0. 1.04058278e-03 + 1.87304895e-02 1.04058278e-03 3.32986489e-02 1.24869933e-02 + 6.24349667e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 2.08116556e-03 2.08116556e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 3.12174833e-03 0. 0. 0. + 1.45681594e-02 1.04058278e-03 0. 2.08116556e-03 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 2.08116556e-03 1.35275759e-02 0. 0. 2.08116556e-03 0. 0. + 1.04058278e-03 1.04058278e-03 8.32466222e-03 0. 1.04058278e-03 + 1.04058278e-03 1.14464108e-02 0. 1.35275759e-02 1.04058278e-03 + 1.04058278e-03 8.32466222e-03 0. 1.04058278e-03 0. 0. 0. + 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 1.35275759e-02 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 0. 1.04058278e-03 2.08116556e-03 3.12174833e-03 + 1.14464108e-02 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 0. + 2.08116556e-03 7.28407968e-03 2.08116556e-03 2.80957352e-02 0. + 1.66493244e-02 1.04058278e-03 2.08116556e-03 1.04058278e-03 + 4.16233111e-03 0. 2.08116556e-03 0. 0. 2.08116556e-03 0. 0. + 1.14464108e-02 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 1.04058278e-03 + 3.12174833e-03 9.36524477e-03 5.20291366e-03 2.39334032e-02 + 1.04058278e-03 2.80957352e-02 0. 1.04058278e-03 0. 2.08116556e-03 + 1.04058278e-03 2.08116556e-03 1.04058278e-03 0. 2.08116556e-03 + 4.16233111e-03 3.12174833e-03 1.87304895e-02 2.70551518e-02 + 3.12174833e-03 1.04058278e-03 4.16233111e-03 1.04058278e-03 0. 0. + 6.24349667e-03 6.24349667e-03 1.04058273e-02 0. 8.32466222e-03 + 5.20291366e-03 9.36524477e-03 2.08116546e-02 8.01248774e-02 + 8.42872038e-02 3.22580673e-02 3.12174833e-03 7.28407968e-03 + 1.45681594e-02 2.08116556e-03 6.24349667e-03 1.04058273e-02 + 2.08116556e-03 1.04058278e-03 1.04058278e-03 0. 8.32466222e-03 + 3.12174833e-03 1.04058273e-02 2.18522381e-02 2.80957352e-02 + 4.16233111e-03 3.12174833e-03 1.04058278e-03 2.08116556e-03 0. + 3.12174833e-03 0. 1.45681594e-02 3.12174833e-03 0. 0. + 2.18522381e-02 1.04058278e-03 2.49739867e-02 8.32466222e-03 + 1.04058278e-03 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 0. + 0. 0. 2.08116556e-03 0. 0. 0. 2.08116556e-03 1.04058278e-03 0. + 1.04058278e-03 1.04058273e-02 0. 0. 1.04058278e-03 1.04058278e-03 + 0. 4.16233111e-03 0. 4.16233111e-03 1.04058278e-03 0. + 1.04058278e-03 2.49739867e-02 2.08116556e-03 2.08116546e-02 + 1.35275759e-02 1.04058273e-02 3.12174833e-03 0. 2.08116556e-03 + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. + 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. + 1.04058278e-03 0. 6.24349667e-03 4.16233111e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 1.04058278e-03 2.08116556e-03 0. 2.08116556e-03 + 0. 0. 3.12174833e-03 1.04058278e-03 1.04058278e-03 2.08116556e-03 + 1.04058273e-02 0. 3.12174833e-03 1.04058278e-03 0. 0. + 2.08116556e-03 0. 5.20291366e-03 0. 1.04058278e-03 1.04058278e-03 + 7.28407968e-03 1.04058278e-03 1.45681594e-02 2.08116556e-03 + 1.04058278e-03 7.28407968e-03 0. 0. 1.04058278e-03 1.04058278e-03 + 0. 2.08116556e-03 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. + 1.04058278e-03 7.28407968e-03 3.12174833e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 3.12174833e-03 + 1.04058278e-03 3.12174833e-03 5.20291366e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 2.08116556e-03 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 3.12174833e-03 0. + 7.28407968e-03 1.35275759e-02 5.20291366e-03 1.66493244e-02 0. + 4.16233111e-03 0. 1.04058278e-03 0. 2.08116556e-03 0. + 1.04058278e-03 0. 0. 0. 2.08116556e-03 1.04058278e-03 + 4.16233111e-03 2.08116556e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. + 2.08116556e-03 1.04058278e-03 0. 2.08116556e-03 1.04058278e-03 0. + 3.12174833e-03 5.20291366e-03 8.32466222e-03 4.37044762e-02 0. + 1.66493244e-02 2.08116556e-03 1.04058278e-03 2.08116556e-03 + 7.28407968e-03 1.04058278e-03 1.04058278e-03 0. 6.24349667e-03 + 1.04058278e-03 0. 3.12174833e-03 2.91363187e-02 2.08116546e-02 + 1.14464108e-02 0. 7.28407968e-03 0. 0. 1.04058278e-03 + 4.16233111e-03 1.24869933e-02 3.12174833e-03 2.08116556e-03 + 7.28407968e-03 1.14464108e-02 7.28407968e-03 3.74609791e-02 + 1.04058281e-01 6.65972978e-02 1.45681594e-02 9.36524477e-03 + 6.24349667e-03 1.35275759e-02 2.08116556e-03 6.24349667e-03 + 5.20291366e-03 1.04058278e-03 0. 0. 0. 6.24349667e-03 + 1.04058278e-03 4.16233111e-03 6.24349667e-03 2.08116546e-02 + 1.04058278e-03 1.04058278e-03 0. 4.16233111e-03 0. 3.12174833e-03 + 1.04058278e-03 4.16233111e-03 0. 0. 0. 2.39334032e-02 + 1.04058278e-03 3.22580673e-02 1.04058273e-02 4.16233111e-03 + 3.12174833e-03 1.04058278e-03 1.04058278e-03 3.12174833e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 4.16233111e-03 + 1.04058278e-03 0. 0. 2.08116556e-03 0. 4.16233111e-03 0. + 7.28407968e-03 0. 0. 1.04058278e-03 3.12174838e-02 1.04058278e-03 + 2.49739867e-02 6.24349667e-03 1.04058273e-02 2.08116556e-03 + 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 6.24349667e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 3.12174833e-03 1.04058278e-03 0. + 0. 1.04058278e-03 0. 2.08116556e-03 0. 1.04058273e-02 + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 1.56087419e-02 + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 2.80957352e-02 0. 1.04058278e-03 0. 1.76899079e-02 0. + 1.04058273e-02 3.12174833e-03 2.08116556e-03 5.20291366e-03 0. + 3.12174833e-03 0. 0. 2.08116556e-03 5.20291366e-03 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 3.12174833e-03 1.04058278e-03 + 3.12174833e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 4.16233111e-03 8.32466222e-03 0. 0. + 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. + 2.08116556e-03 2.08116556e-03 2.08116556e-03 1.35275759e-02 + 8.32466222e-03 4.68262248e-02 0. 2.60145701e-02 1.04058278e-03 + 3.12174833e-03 0. 5.20291366e-03 0. 1.04058278e-03 0. + 3.12174833e-03 0. 3.12174833e-03 2.08116556e-03 2.08116556e-03 0. + 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. + 0. 0. 2.08116556e-03 0. 7.28407968e-03 8.32466222e-03 + 4.47450578e-02 0. 3.12174838e-02 3.12174833e-03 0. 0. + 1.14464108e-02 0. 2.08116556e-03 0. 0. 1.04058278e-03 0. + 2.08116556e-03 1.56087419e-02 3.43392305e-02 3.01769003e-02 + 1.04058278e-03 1.35275759e-02 1.04058278e-03 2.08116556e-03 0. + 5.20291366e-03 1.04058273e-02 1.14464108e-02 0. 9.36524477e-03 + 1.45681594e-02 7.28407968e-03 1.24869933e-02 7.59625435e-02 + 4.78668064e-02 1.97710730e-02 2.08116556e-03 2.08116556e-03 + 7.28407968e-03 2.08116556e-03 1.04058278e-03 1.04058273e-02 0. + 2.08116556e-03 0. 1.04058278e-03 5.20291366e-03 2.08116556e-03 + 1.35275759e-02 1.31113425e-01 1.24869933e-02 1.04058278e-03 0. + 1.04058278e-03 5.20291366e-03 0. 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 1.04058278e-03 1.04058278e-03 0. 1.35275759e-02 0. + 3.12174838e-02 2.91363187e-02 4.16233111e-03 0. 1.04058278e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 2.08116556e-03 + 1.04058273e-02 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 3.01769003e-02 0. + 1.24869933e-02 4.16233111e-03 1.87304895e-02 1.04058278e-03 0. + 1.04058278e-03 4.16233111e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. + 2.08116556e-03 0. 0. 1.04058278e-03 5.20291366e-03 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 1.04058278e-03 7.28407968e-03 1.04058278e-03 + 0. 2.08116556e-03 1.04058278e-03 0. 1.04058278e-03 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 2.18522381e-02 0. + 0. 0. 2.08116556e-03 0. 0. 0. 9.36524477e-03 1.04058278e-03 0. + 1.04058278e-03 8.32466222e-03 0. 3.12174833e-03 4.16233111e-03 + 1.04058278e-03 6.24349667e-03 0. 6.24349667e-03 1.04058278e-03 + 2.08116556e-03 1.04058278e-03 6.24349667e-03 0. 1.04058278e-03 0. + 0. 0. 0. 0. 8.32466222e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 + 0. 9.36524477e-03 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 3.12174833e-03 0. + 6.24349667e-03 3.12174833e-03 1.87304895e-02 0. 1.97710730e-02 0. + 0. 0. 1.35275759e-02 0. 1.04058278e-03 0. 0. 0. 0. 0. + 6.24349667e-03 3.12174833e-03 1.04058278e-03 0. 2.08116556e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 1.14464108e-02 2.70551518e-02 0. 1.56087419e-02 2.08116556e-03 0. + 0. 9.36524477e-03 0. 1.04058278e-03 0. 1.04058278e-03 + 2.08116556e-03 3.12174833e-03 0. 1.35275759e-02 6.55567124e-02 + 3.32986489e-02 1.04058278e-03 1.04058273e-02 1.04058278e-03 + 1.04058278e-03 0. 5.20291366e-03 1.35275759e-02 1.45681594e-02 + 2.08116556e-03 1.24869933e-02 1.24869933e-02 8.32466222e-03 + 1.24869933e-02 6.24349676e-02 5.09885550e-02 3.53798158e-02 + 1.04058278e-03 6.24349667e-03 5.20291366e-03 0. 5.20291366e-03 + 1.14464108e-02 1.04058278e-03 0. 0. 0. 6.24349667e-03 0. + 8.32466222e-03 8.32466222e-03 2.18522381e-02 6.24349667e-03 0. + 2.08116556e-03 1.04058278e-03 0. 5.20291366e-03 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 0. 0. 2.60145701e-02 1.04058278e-03 + 5.61914705e-02 1.97710730e-02 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.35275759e-02 2.08116556e-03 + 0. 0. 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 + 3.12174833e-03 0. 0. 1.04058278e-03 1.45681594e-02 0. + 1.66493244e-02 6.24349667e-03 1.45681594e-02 5.20291366e-03 0. + 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 2.08116556e-03 0. + 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 2.08116556e-03 0. 1.04058278e-03 2.08116556e-03 + 5.20291366e-03 2.08116556e-03 1.04058278e-03 0. 1.04058278e-03 0. + 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 6.24349667e-03 1.04058278e-03 0. 3.12174833e-03 0. 0. + 1.04058278e-03 0. 3.12174833e-03 0. 0. 0. 7.28407968e-03 0. + 7.28407968e-03 3.12174833e-03 2.08116556e-03 7.28407968e-03 0. + 5.20291366e-03 0. 1.04058278e-03 1.04058278e-03 3.12174833e-03 0. + 0. 0. 0. 0. 0. 0. 1.04058273e-02 0. 0. 0. 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 0. 2.08116556e-03 6.24349667e-03 0. + 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 8.32466222e-03 + 3.12174833e-03 2.70551518e-02 0. 1.97710730e-02 4.16233111e-03 + 3.12174833e-03 0. 8.32466222e-03 1.04058278e-03 2.08116556e-03 0. + 1.04058278e-03 1.04058278e-03 0. 0. 7.28407968e-03 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 2.08116556e-03 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 1.04058278e-03 1.14464108e-02 8.32466222e-03 + 1.47762761e-01 0. 2.18522381e-02 3.12174833e-03 0. 2.08116556e-03 + 1.35275759e-02 2.08116556e-03 3.12174833e-03 1.04058278e-03 + 4.16233111e-03 0. 2.08116556e-03 2.08116556e-03 2.39334032e-02 + 1.04058273e-02 1.97710730e-02 0. 1.24869933e-02 2.08116556e-03 0. + 0. 4.16233111e-03 1.04058278e-03 8.32466222e-03 1.04058278e-03 + 7.28407968e-03 7.28407968e-03 7.28407968e-03 1.66493244e-02 + 8.53277892e-02 1.24869933e-02 9.36524477e-03 0. 1.04058278e-03 + 9.36524477e-03 0. 2.08116556e-03 6.24349676e-02 0. 0. 0. 0. + 3.12174833e-03 0. 0. 2.08116546e-02 7.28407968e-03 2.08116556e-03 + 1.04058278e-03 0. 0. 0. 0. 3.12174833e-03 1.04058278e-03 0. 0. 0. + 3.01769003e-02 2.08116556e-03 1.87304895e-02 5.93132190e-02 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. + 4.16233111e-03 0. 0. 0. 1.56087419e-02 0. 5.20291366e-03 + 1.45681594e-02 3.12174833e-03 0. 0. 1.04058278e-03 3.12174833e-03 + 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 3.12174833e-03 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 0. 0. 2.18522381e-02 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 2.08116556e-03 + 1.04058278e-03 7.28407949e-02 1.04058278e-03 0. 0. 7.18002096e-02 + 1.04058278e-03 1.87304895e-02 1.66493244e-02 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. 6.65972978e-02 0. 0. 0. + 0. 0. 0. 0. 2.39334032e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.45681594e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 5.20291366e-03 + 2.08116556e-03 1.24869933e-02 0. 4.16233111e-03 1.04058278e-03 + 5.20291366e-03 0. 4.78668064e-02 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.45681594e-02 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. + 3.12174833e-03 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. + 3.85015644e-02 1.04058278e-03 3.01769003e-02 0. 2.08116556e-03 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 4.16233111e-03 + 3.12174833e-03 1.56087419e-02 0. 8.32466222e-03 0. 1.04058278e-03 + 0. 6.24349667e-03 3.12174833e-03 9.36524477e-03 0. 2.08116556e-03 + 7.28407968e-03 1.66493244e-02 3.12174833e-03 1.17585853e-01 + 7.28407968e-03 1.24869933e-02 0. 5.20291366e-03 6.24349667e-03 0. + 2.08116556e-03 8.32466222e-03 1.04058278e-03 0. 0. 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 1.87304895e-02 7.07596317e-02 + 9.36524477e-03 1.66493244e-02 0. 1.04058278e-03 0. 1.04058278e-03 + 0. 2.08116556e-03 7.28407968e-03 2.08116556e-03 0. 0. + 3.32986489e-02 3.12174833e-03 1.03017695e-01 1.25910521e-01 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 8.32466222e-03 + 1.04058278e-03 0. 0. 1.66493244e-02 0. 2.08116546e-02 + 8.32466222e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 7.28407968e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 2.08116556e-03 0. + 0. 1.04058278e-03 6.24349667e-03 0. 2.28928216e-02 4.16233111e-03 + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 3.12174833e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 0. + 9.36524477e-03 0. 1.04058278e-03 0. 0. 0. 3.12174833e-03 0. 0. 0. + 0. 1.04058278e-03 0. 0. 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 4.16233111e-03 7.28407968e-03 2.91363187e-02 0. + 0. 0. 0. 1.04058278e-03 3.12174833e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058273e-02 1.09261192e-01 1.61290333e-01 0. + 2.08116556e-03 0. 0. 0. 2.08116556e-03 0. 1.04058278e-03 0. + 1.04058278e-03 1.97710730e-02 3.12174833e-03 1.76899079e-02 + 3.85015644e-02 5.30697219e-02 1.56087419e-02 3.12174833e-03 + 5.20291366e-03 1.14464108e-02 0. 5.20291366e-03 3.12174833e-03 + 2.08116556e-03 0. 1.04058278e-03 3.12174833e-03 4.16233111e-03 0. + 1.24869933e-02 2.08116546e-02 2.18522381e-02 1.04058278e-03 0. 0. + 4.16233111e-03 0. 1.04058278e-03 1.04058278e-03 3.12174833e-03 + 1.04058278e-03 0. 2.08116556e-03 1.76899079e-02 1.04058278e-03 + 2.49739867e-02 3.12174838e-02 2.08116556e-03 2.08116556e-03 0. + 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. 1.04058278e-03 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 1.14464108e-02 2.08116556e-03 0. + 0. 0. 0. 2.08116556e-03 1.04058278e-03 5.20291366e-03 0. 0. + 1.04058278e-03 2.08116546e-02 0. 2.70551518e-02 5.20291366e-03 + 2.08116546e-02 2.08116556e-03 1.04058278e-03 3.12174833e-03 + 2.08116556e-03 0. 1.04058278e-03 3.12174833e-03 1.04058278e-03 0. + 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 2.08116556e-03 + 7.28407968e-03 2.08116556e-03 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.56087419e-02 0. + 1.04058278e-03 0. 2.08116556e-03 0. 0. 1.04058278e-03 + 7.28407968e-03 0. 1.04058278e-03 0. 8.32466222e-03 0. + 7.28407968e-03 2.08116556e-03 1.04058278e-03 8.32466222e-03 + 1.04058278e-03 7.28407968e-03 0. 0. 0. 7.28407968e-03 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 6.24349667e-03 1.04058278e-03 + 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 1.04058278e-03 0. 2.08116556e-03 7.28407968e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 3.12174833e-03 + 1.04058278e-03 4.16233111e-03 1.04058273e-02 1.04058273e-02 + 2.60145701e-02 0. 2.28928216e-02 0. 0. 2.08116556e-03 + 1.66493244e-02 0. 0. 0. 2.08116556e-03 0. 0. 0. 6.24349667e-03 + 3.12174833e-03 2.08116556e-03 0. 1.04058278e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. + 1.04058278e-03 1.04058278e-03 6.24349667e-03 8.32466222e-03 + 4.26638946e-02 0. 1.97710730e-02 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 8.32466222e-03 1.04058278e-03 1.04058278e-03 0. + 3.12174833e-03 0. 0. 4.16233111e-03 2.08116546e-02 4.57856432e-02 + 4.68262248e-02 3.12174833e-03 7.28407968e-03 2.08116556e-03 0. + 1.04058278e-03 2.08116556e-03 1.14464108e-02 7.28407968e-03 0. + 1.24869933e-02 1.24869933e-02 1.04058273e-02 2.39334032e-02 + 8.63683671e-02 8.22060406e-02 3.74609791e-02 2.08116556e-03 + 7.28407968e-03 1.35275759e-02 2.08116556e-03 9.36524477e-03 + 1.04058273e-02 3.12174833e-03 1.04058278e-03 0. 1.04058278e-03 + 2.08116556e-03 3.12174833e-03 1.76899079e-02 2.39334032e-02 + 3.01769003e-02 2.08116556e-03 1.04058278e-03 2.08116556e-03 + 6.24349667e-03 0. 2.08116556e-03 0. 1.04058273e-02 2.08116556e-03 + 0. 0. 1.66493244e-02 2.08116556e-03 3.22580673e-02 1.45681594e-02 + 3.12174833e-03 0. 0. 0. 2.08116556e-03 0. 2.08116556e-03 + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. + 5.20291366e-03 8.32466222e-03 2.08116556e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 2.08116556e-03 0. 4.16233111e-03 3.12174833e-03 + 0. 1.04058278e-03 8.32466222e-03 0. 1.76899079e-02 1.14464108e-02 + 1.14464108e-02 2.08116556e-03 1.04058278e-03 5.20291366e-03 + 2.08116556e-03 0. 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 + 0. 0. 2.08116556e-03 0. 2.08116556e-03 2.08116556e-03 + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. + 0. 0. 4.16233111e-03 0. 1.04058278e-03 1.04058278e-03 + 5.20291366e-03 5.20291366e-03 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 2.08116556e-03 0. 3.12174833e-03 0. + 1.45681594e-02 1.04058278e-03 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 5.20291366e-03 0. + 0. 0. 4.16233111e-03 0. 1.04058273e-02 5.20291366e-03 + 4.16233111e-03 1.04058273e-02 0. 5.20291366e-03 0. 2.08116556e-03 + 0. 6.24349667e-03 1.04058278e-03 2.08116556e-03 0. 0. 0. + 2.08116556e-03 1.04058278e-03 1.56087419e-02 2.08116556e-03 + 4.16233111e-03 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. + 2.08116556e-03 0. 0. 3.12174833e-03 1.04058278e-03 2.08116556e-03 + 3.12174833e-03 8.32466222e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 3.12174833e-03 + 7.28407968e-03 3.12174833e-03 8.32466222e-03 0. 9.36524477e-03 + 1.04058278e-03 1.04058278e-03 1.04058278e-03 8.32466222e-03 0. + 3.12174833e-03 0. 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. + 8.32466222e-03 3.12174833e-03 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. + 1.04058278e-03 6.24349667e-03 1.45681594e-02 2.39334032e-02 + 1.04058278e-03 1.45681594e-02 0. 0. 4.16233111e-03 1.76899079e-02 + 0. 2.08116556e-03 0. 3.12174833e-03 1.04058278e-03 2.08116556e-03 + 4.16233111e-03 2.39334032e-02 9.36524477e-03 1.24869933e-02 0. + 1.14464108e-02 1.04058278e-03 0. 2.08116556e-03 1.04058278e-03 + 1.24869933e-02 7.28407968e-03 2.08116556e-03 1.24869933e-02 + 8.32466222e-03 4.16233111e-03 2.91363187e-02 1.00936532e-01 + 7.59625435e-02 2.60145701e-02 1.04058278e-03 3.12174833e-03 + 5.20291366e-03 4.16233111e-03 4.16233111e-03 9.36524477e-03 + 4.16233111e-03 2.08116556e-03 0. 0. 5.20291366e-03 1.04058278e-03 + 3.12174833e-03 7.28407968e-03 1.66493244e-02 0. 3.12174833e-03 + 1.04058278e-03 3.12174833e-03 2.08116556e-03 8.32466222e-03 + 1.04058278e-03 4.16233111e-03 0. 0. 0. 2.08116546e-02 + 1.04058278e-03 2.39334032e-02 6.24349667e-03 3.12174833e-03 + 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 3.12174833e-03 3.12174833e-03 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 1.04058278e-03 2.08116556e-03 0. 0. 1.04058278e-03 + 2.08116556e-03 1.04058278e-03 1.97710730e-02 3.12174833e-03 + 6.24349667e-03 4.16233111e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 0. 0. 0. 0. 0. 1.04058278e-03 2.08116556e-03 0. 0. 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 2.08116556e-03 + 4.16233111e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 2.08116556e-03 5.20291366e-03 3.12174833e-03 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 2.08116556e-03 0. 0. 0. + 1.04058278e-03 0. 3.12174833e-03 2.08116556e-03 8.32466222e-03 + 9.36524477e-03 0. 3.12174833e-03 1.04058278e-03 1.04058278e-03 0. + 4.16233111e-03 1.04058278e-03 1.04058278e-03 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 7.28407968e-03 2.08116556e-03 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 2.08116556e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 7.28407968e-03 6.24349667e-03 + 2.08116556e-03 1.04058278e-03 0. 0. 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 3.12174833e-03 2.08116556e-03 0. 1.04058278e-03 0. 0. 0. + 1.04058278e-03 0. 4.16233111e-03 1.56087419e-02 2.70551518e-02 0. + 7.28407968e-03 2.08116556e-03 3.12174833e-03 0. 7.28407968e-03 + 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 0. + 0. 5.20291366e-03 0. 3.12174833e-03 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 4.16233111e-03 1.56087419e-02 1.01977110e-01 0. + 1.87304895e-02 1.04058278e-03 1.04058278e-03 0. 1.45681594e-02 + 2.08116556e-03 4.16233111e-03 0. 1.04058278e-03 2.08116556e-03 + 2.08116556e-03 1.04058278e-03 2.60145701e-02 8.22060406e-02 + 6.24349676e-02 0. 1.35275759e-02 0. 1.04058278e-03 2.08116556e-03 + 1.24869933e-02 6.24349667e-03 6.24349667e-03 0. 3.12174833e-03 + 5.20291366e-03 4.16233111e-03 1.76899079e-02 9.26118642e-02 + 2.28928216e-02 1.04058273e-02 1.04058278e-03 7.28407968e-03 + 6.24349667e-03 3.12174833e-03 4.16233111e-03 2.49739867e-02 + 1.04058278e-03 0. 0. 0. 3.12174833e-03 0. 1.04058273e-02 + 2.80957352e-02 5.20291366e-03 2.08116556e-03 1.04058278e-03 + 2.08116556e-03 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 + 7.28407968e-03 1.04058278e-03 0. 1.04058278e-03 2.39334032e-02 0. + 6.55567124e-02 2.80957352e-02 0. 0. 0. 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. + 0. 0. 0. 0. 0. 0. 1.87304895e-02 0. 0. 0. 2.08116546e-02 0. + 6.24349667e-03 8.32466222e-03 5.20291366e-03 2.08116556e-03 0. + 2.08116556e-03 1.04058278e-03 0. 1.04058278e-03 0. 3.12174833e-03 + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 3.12174833e-03 0. + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. + 1.04058278e-03 2.39334032e-02 2.08116556e-03 0. 0. 0. 0. 0. + 1.04058278e-03 2.49739867e-02 0. 3.12174833e-03 0. 2.39334032e-02 + 1.04058278e-03 9.36524477e-03 4.16233111e-03 0. 6.24349667e-03 + 1.04058278e-03 1.14464108e-02 1.04058278e-03 1.04058278e-03 0. + 3.32986489e-02 0. 0. 0. 0. 0. 0. 0. 1.56087419e-02 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 + 5.20291366e-03 4.16233111e-03 1.56087419e-02 0. 2.18522381e-02 0. + 0. 2.08116556e-03 2.08116546e-02 0. 0. 0. 0. 1.04058278e-03 0. 0. + 1.35275759e-02 0. 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 4.16233111e-03 1.76899079e-02 3.95421460e-02 + 1.04058278e-03 1.56087419e-02 0. 0. 0. 1.24869933e-02 0. 0. 0. 0. + 0. 0. 0. 7.28407968e-03 1.23829350e-01 4.68262248e-02 + 2.08116556e-03 8.32466222e-03 2.08116556e-03 0. 0. 3.12174833e-03 + 2.39334032e-02 5.20291366e-03 1.04058278e-03 7.28407968e-03 + 1.04058273e-02 3.12174833e-03 8.32466222e-03 4.26638946e-02 + 3.12174838e-02 4.99479733e-02 2.08116556e-03 9.36524477e-03 + 9.36524477e-03 1.04058278e-03 9.36524477e-03 2.49739867e-02 + 1.04058278e-03 1.04058278e-03 0. 0. 5.20291366e-03 0. + 2.39334032e-02 1.20707601e-01 3.22580673e-02 1.56087419e-02 + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 0. 3.12174833e-03 + 2.08116556e-03 1.04058278e-03 0. 1.04058278e-03 1.24869933e-02 0. + 1.12382941e-01 6.45161346e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 6.24349667e-03 0. 0. 0. 1.97710730e-02 0. 1.24869933e-02 + 5.20291366e-03 1.04058278e-03 2.08116556e-03 0. 2.08116556e-03 + 1.04058278e-03 0. 2.08116556e-03 2.08116556e-03 0. 0. 0. 0. + 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. + 3.12174833e-03 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. + 3.12174833e-03 0. 0. 1.04058278e-03 5.20291366e-03 0. + 2.08116556e-03 4.16233111e-03 1.04058278e-03 3.12174833e-03 0. + 8.32466222e-03 0. 0. 1.04058278e-03 1.35275759e-02 0. 0. 0. 0. 0. + 0. 0. 1.45681594e-02 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 1.04058273e-02 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. + 9.36524477e-03 1.04058278e-03 9.36524477e-03 0. 6.24349667e-03 0. + 0. 0. 8.32466222e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 9.36524477e-03 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 5.20291366e-03 + 5.20291366e-03 2.39334032e-02 0. 2.08116556e-03 2.08116556e-03 0. + 0. 6.24349667e-03 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. + 7.28407968e-03 3.22580673e-02 6.34755492e-02 1.14464108e-02 + 1.04058278e-03 2.08116556e-03 0. 0. 1.04058278e-03 2.08116556e-03 + 4.16233111e-03 3.12174833e-03 0. 4.16233111e-03 1.04058278e-03 + 1.04058278e-03 3.01769003e-02 4.99479733e-02 2.80957352e-02 + 3.64203975e-02 1.04058278e-03 6.24349667e-03 4.16233111e-03 + 4.16233111e-03 0. 1.66493244e-02 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 7.28407968e-03 3.22580673e-02 3.95421460e-02 + 6.24349667e-03 3.12174833e-03 1.04058278e-03 6.24349667e-03 + 3.12174833e-03 4.16233111e-03 2.08116556e-03 3.12174833e-03 0. 0. + 1.04058278e-03 3.32986489e-02 4.16233111e-03 7.28407949e-02 + 6.13943823e-02 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 2.08116556e-03 5.20291366e-03 2.08116556e-03 0. + 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 0. 1.04058278e-03 + 0. 0. 0. 0. 1.04058278e-03 1.04058273e-02 1.35275759e-02 + 4.16233111e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 2.08116556e-03 0. + 1.04058278e-03 3.12174833e-03 1.04058278e-03 1.04058278e-03 0. 0. + 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 + 1.45681594e-02 2.08116556e-03 0. 0. 7.28407968e-03 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 3.12174833e-03 1.04058278e-03 0. 0. + 1.14464108e-02 0. 1.45681594e-02 2.49739867e-02 0. 2.08116556e-03 + 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. + 0. 0. 0. 1.04058278e-03 2.08116556e-03 8.32466222e-03 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 5.20291366e-03 1.04058278e-03 1.14464108e-02 0. 0. + 1.04058278e-03 2.08116556e-03 0. 6.24349667e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 8.32466222e-03 0. 1.04058278e-03 0. 0. 0. + 2.08116556e-03 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. + 2.08116556e-03 1.35275759e-02 6.24349667e-03 1.46722168e-01 0. + 9.36524477e-03 0. 1.04058278e-03 0. 3.12174833e-03 1.04058278e-03 + 3.12174833e-03 0. 0. 1.04058278e-03 3.12174833e-03 3.12174833e-03 + 3.53798158e-02 1.14464108e-02 1.14464108e-02 0. 1.04058278e-03 + 2.08116556e-03 0. 0. 2.08116556e-03 1.04058278e-03 6.24349667e-03 + 0. 3.12174833e-03 1.24869933e-02 1.04058273e-02 3.01769003e-02 + 9.26118642e-02 6.24349667e-03 4.16233111e-03 0. 2.08116556e-03 + 8.32466222e-03 3.12174833e-03 0. 2.60145701e-02 0. 0. 0. 0. + 2.08116556e-03 0. 4.16233111e-03 8.32466222e-03 1.24869933e-02 + 1.04058278e-03 0. 0. 3.12174833e-03 2.08116556e-03 2.08116556e-03 + 1.04058278e-03 4.16233111e-03 0. 0. 0. 7.49219581e-02 + 2.08116556e-03 5.09885550e-02 4.57856432e-02 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 5.20291366e-03 0. 0. 0. 2.08116556e-03 + 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 1.04058278e-03 + 5.41103035e-02 0. 3.22580673e-02 2.18522381e-02 1.14464108e-02 + 3.12174833e-03 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 2.08116556e-03 0. 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 2.60145701e-02 0. 0. 0. 1.04058273e-02 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 1.56087419e-02 0. 0. 2.08116556e-03 + 7.70031288e-02 3.12174833e-03 2.18522381e-02 2.80957352e-02 + 1.04058278e-03 3.12174833e-03 0. 2.08116556e-03 0. 0. 0. + 1.14464108e-02 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 0. 0. 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 6.24349667e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 2.08116556e-03 8.32466222e-03 1.04058278e-03 3.22580673e-02 0. + 4.26638946e-02 0. 6.24349667e-03 0. 8.32466222e-03 0. 0. 0. 0. 0. + 0. 0. 6.24349667e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 4.16233111e-03 0. 9.36524477e-03 0. 4.89073917e-02 + 0. 1.76899079e-02 0. 1.04058278e-03 1.04058278e-03 4.16233111e-03 + 0. 0. 0. 1.04058278e-03 0. 0. 0. 5.20291366e-03 3.12174833e-03 + 1.56087419e-02 0. 6.24349667e-03 1.04058278e-03 5.20291366e-03 0. + 9.36524477e-03 5.20291366e-03 5.20291366e-03 0. 3.12174833e-03 + 9.36524477e-03 2.39334032e-02 1.14464108e-02 7.28407949e-02 + 7.28407968e-03 1.66493244e-02 0. 2.08116556e-03 1.04058278e-03 + 2.08116556e-03 4.16233111e-03 8.32466222e-03 0. 0. 0. 0. + 6.24349667e-03 0. 1.87304895e-02 5.72320521e-02 6.24349667e-03 + 9.36524477e-03 0. 1.04058278e-03 1.04058278e-03 0. 0. + 2.08116556e-03 6.24349667e-03 2.08116556e-03 0. 0. 1.24869933e-02 + 6.24349667e-03 6.03538007e-02 7.90842921e-02 1.04058278e-03 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 7.28407968e-03 1.04058278e-03 6.24349667e-03 4.16233111e-03 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 2.49739867e-02 0. 0. 0. 0. 0. 0. 0. 1.87304895e-02 + 0. 0. 0. 1.97710730e-02 0. 4.16233111e-03 2.08116556e-03 0. + 1.04058278e-03 0. 1.04058278e-03 0. 1.04058278e-03 0. + 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. 6.24349667e-03 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 2.08116556e-03 1.14464108e-02 0. + 2.08116556e-03 0. 1.04058278e-03 0. 8.32466222e-03 0. 0. 0. 0. 0. + 0. 0. 2.08116556e-03 0. 5.20291366e-03 0. 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 1.66493244e-02 + 1.38397515e-01 0. 1.04058273e-02 0. 1.04058278e-03 0. + 8.32466222e-03 0. 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 + 6.24349667e-03 9.88553613e-02 1.42559841e-01 0. 4.16233111e-03 + 1.04058278e-03 2.08116556e-03 0. 6.24349667e-03 9.36524477e-03 + 8.32466222e-03 0. 4.16233111e-03 1.24869933e-02 1.14464108e-02 + 1.45681594e-02 3.43392305e-02 7.38813803e-02 4.05827276e-02 + 2.08116556e-03 6.24349667e-03 6.24349667e-03 1.04058278e-03 + 3.12174833e-03 4.16233111e-03 2.08116556e-03 0. 0. 0. + 3.12174833e-03 1.04058278e-03 2.60145701e-02 3.53798158e-02 + 4.16233093e-02 7.28407968e-03 2.08116556e-03 2.08116556e-03 + 4.16233111e-03 0. 5.20291366e-03 1.04058278e-03 6.24349667e-03 0. + 1.04058278e-03 0. 9.36524477e-03 1.04058278e-03 5.51508889e-02 + 2.70551518e-02 7.28407968e-03 3.12174833e-03 1.04058278e-03 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 6.24349667e-03 0. + 1.04058278e-03 1.04058278e-03 0. 0. 2.08116556e-03 0. + 3.12174833e-03 0. 0. 0. 6.24349667e-03 0. 1.45681594e-02 + 6.24349667e-03 8.32466222e-03 5.20291366e-03 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 2.08116556e-03 7.28407968e-03 4.16233111e-03 + 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 2.08116556e-03 7.28407968e-03 2.08116556e-03 0. 0. + 0. 0. 0. 1.04058278e-03 4.16233111e-03 0. 0. 0. 4.16233111e-03 0. + 1.35275759e-02 3.12174833e-03 2.08116556e-03 2.08116556e-03 0. 0. + 0. 0. 1.04058278e-03 5.20291366e-03 0. 0. 0. 1.04058278e-03 0. 0. + 2.08116556e-03 4.16233111e-03 3.12174833e-03 4.16233111e-03 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 5.20291366e-03 + 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 0. 1.04058278e-03 0. 2.08116556e-03 8.32466222e-03 + 5.20291366e-03 1.14464108e-02 0. 7.28407968e-03 0. 0. 0. + 5.20291366e-03 0. 1.04058278e-03 0. 0. 2.08116556e-03 0. + 2.08116556e-03 1.14464108e-02 0. 1.04058278e-03 1.04058278e-03 0. + 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 1.04058278e-03 + 1.04058278e-03 2.08116556e-03 1.45681594e-02 5.51508889e-02 0. + 2.08116546e-02 3.12174833e-03 1.04058278e-03 1.04058278e-03 + 7.28407968e-03 2.08116556e-03 3.12174833e-03 0. 2.08116556e-03 0. + 2.08116556e-03 5.20291366e-03 3.74609791e-02 3.32986489e-02 + 1.97710730e-02 2.08116556e-03 4.16233111e-03 0. 0. 3.12174833e-03 + 2.08116556e-03 1.24869933e-02 1.45681594e-02 1.04058278e-03 + 5.20291366e-03 9.36524477e-03 3.12174833e-03 3.74609791e-02 + 9.05307010e-02 8.11654553e-02 3.12174838e-02 1.04058278e-03 + 1.35275759e-02 5.20291366e-03 1.04058278e-03 1.24869933e-02 + 8.32466222e-03 7.28407968e-03 2.08116556e-03 0. 0. 4.16233111e-03 + 1.04058278e-03 9.36524477e-03 2.49739867e-02 3.12174838e-02 + 7.28407968e-03 2.08116556e-03 1.04058278e-03 4.16233111e-03 0. + 4.16233111e-03 1.04058278e-03 5.20291366e-03 2.08116556e-03 0. + 1.04058278e-03 1.87304895e-02 0. 3.01769003e-02 1.35275759e-02 + 5.20291366e-03 0. 1.04058278e-03 2.08116556e-03 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 6.24349667e-03 3.12174833e-03 1.04058278e-03 0. 1.04058278e-03 0. + 1.04058278e-03 1.04058278e-03 5.20291366e-03 0. 0. 0. + 1.04058278e-03 0. 2.18522381e-02 1.04058273e-02 2.08116556e-03 + 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 7.28407968e-03 4.16233111e-03 + 1.04058278e-03 4.16233111e-03 2.08116556e-03 0. 1.04058278e-03 0. + 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 1.76899079e-02 + 2.08116556e-03 2.08116556e-03 2.08116556e-03 0. 0. 2.08116556e-03 + 0. 5.20291366e-03 1.04058278e-03 0. 0. 5.20291366e-03 0. + 9.36524477e-03 3.12174833e-03 7.28407968e-03 8.32466222e-03 0. + 6.24349667e-03 1.04058278e-03 1.04058278e-03 0. 4.16233111e-03 0. + 0. 0. 0. 0. 1.04058278e-03 3.12174833e-03 1.56087419e-02 + 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 0. 1.04058278e-03 0. 5.20291366e-03 5.20291366e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 2.08116556e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 1.24869933e-02 7.28407968e-03 2.70551518e-02 + 1.04058278e-03 2.80957352e-02 0. 1.04058278e-03 0. 9.36524477e-03 + 2.08116556e-03 1.04058278e-03 0. 2.08116556e-03 1.04058278e-03 + 1.04058278e-03 2.08116556e-03 1.14464108e-02 2.08116556e-03 + 1.04058278e-03 0. 2.08116556e-03 0. 0. 0. 2.08116556e-03 + 2.08116556e-03 2.08116556e-03 0. 0. 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 2.08116556e-03 1.87304895e-02 2.39334032e-02 + 3.12174833e-03 2.49739867e-02 0. 0. 1.04058278e-03 9.36524477e-03 + 0. 2.08116556e-03 0. 1.04058278e-03 2.08116556e-03 1.04058278e-03 + 2.08116556e-03 1.97710730e-02 1.76899079e-02 1.14464108e-02 + 1.04058278e-03 8.32466222e-03 1.04058278e-03 0. 0. 1.04058273e-02 + 1.45681594e-02 8.32466222e-03 3.12174833e-03 8.32466222e-03 + 4.16233111e-03 7.28407968e-03 3.01769003e-02 9.67741981e-02 + 2.60145701e-02 3.22580673e-02 0. 4.16233111e-03 3.12174833e-03 + 1.04058278e-03 3.12174833e-03 2.08116556e-03 3.12174833e-03 + 1.04058278e-03 0. 0. 2.08116556e-03 0. 4.16233111e-03 + 3.12174838e-02 3.64203975e-02 1.04058273e-02 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 2.08116556e-03 1.04058278e-03 0. + 1.04058278e-03 1.04058273e-02 5.20291366e-03 1.87304895e-02 + 1.24869933e-02 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 9.36524477e-03 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 0. 5.20291366e-03 + 0. 6.24349667e-03 3.12174833e-03 8.32466222e-03 0. 0. + 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 2.08116556e-03 0. 9.36524477e-03 2.08116556e-03 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 4.57856432e-02 2.08116556e-03 0. 0. 0. 0. 0. 0. + 2.49739867e-02 0. 0. 0. 4.16233111e-03 1.04058278e-03 + 1.04058273e-02 0. 0. 3.12174833e-03 0. 2.08116556e-03 0. 0. 0. + 4.16233111e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 6.24349667e-03 + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 2.08116556e-03 5.20291366e-03 1.24869933e-02 0. + 3.12174833e-03 1.04058278e-03 3.12174833e-03 0. 4.16233111e-03 0. + 0. 0. 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. + 1.04058278e-03 2.08116556e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 0. 0. 2.08116556e-03 0. 2.39334032e-02 + 5.41103035e-02 0. 9.36524477e-03 0. 1.04058278e-03 0. + 8.32466222e-03 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 3.12174833e-03 2.39334032e-02 1.51925087e-01 1.06139444e-01 + 2.08116556e-03 9.36524477e-03 1.04058278e-03 2.08116556e-03 + 3.12174833e-03 7.28407968e-03 4.47450578e-02 1.24869933e-02 0. + 3.12174833e-03 6.24349667e-03 6.24349667e-03 3.32986489e-02 + 5.82726374e-02 1.76899079e-02 1.14464108e-02 0. 5.20291366e-03 + 1.04058273e-02 0. 3.12174833e-03 2.70551518e-02 0. 0. 0. 0. + 6.24349667e-03 0. 3.12174833e-03 2.91363187e-02 1.66493244e-02 + 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. 0. 4.16233111e-03 0. 0. + 0. 9.36524477e-03 3.12174833e-03 2.08116546e-02 1.97710730e-02 + 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 1.04058278e-03 4.16233111e-03 0. 0. 0. + 2.08116556e-03 0. 1.04058278e-03 0. 1.45681594e-02 1.04058278e-03 + 1.04058278e-03 0. 3.12174838e-02 0. 3.12174833e-03 6.24349667e-03 + 1.66493244e-02 5.20291366e-03 0. 2.08116556e-03 4.16233111e-03 0. + 1.04058278e-03 0. 2.08116556e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. + 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 0. 0. 1.66493244e-02 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 3.95421460e-02 2.08116556e-03 + 2.08116556e-03 0. 3.12174833e-03 0. 0. 1.04058278e-03 + 4.57856432e-02 1.04058278e-03 0. 0. 3.32986489e-02 0. + 7.28407968e-03 2.08116556e-03 0. 7.28407968e-03 0. 1.24869933e-02 + 0. 0. 0. 3.22580673e-02 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 1.24869933e-02 0. 1.04058278e-03 0. 2.08116556e-03 + 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. 1.45681594e-02 + 3.12174833e-03 2.60145701e-02 0. 4.47450578e-02 0. 1.04058278e-03 + 1.04058278e-03 2.80957352e-02 0. 0. 0. 0. 0. 0. 0. 1.24869933e-02 + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 2.08116556e-03 0. 1.04058278e-03 0. 4.16233111e-03 1.45681594e-02 + 2.60145701e-02 0. 1.04058273e-02 0. 0. 0. 8.32466222e-03 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 1.35275759e-02 + 4.05827276e-02 4.37044762e-02 1.04058278e-03 7.28407968e-03 0. 0. + 1.04058278e-03 2.08116556e-03 3.22580673e-02 1.56087419e-02 0. + 2.60145701e-02 1.35275759e-02 1.24869933e-02 5.20291366e-03 + 4.47450578e-02 5.82726374e-02 5.72320521e-02 1.04058278e-03 + 4.16233111e-03 2.08116556e-03 0. 4.16233111e-03 1.24869933e-02 + 1.04058278e-03 3.12174833e-03 0. 0. 7.28407968e-03 1.04058278e-03 + 2.08116546e-02 3.22580673e-02 5.20291403e-02 1.56087419e-02 + 2.08116556e-03 2.08116556e-03 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 4.16233111e-03 1.04058273e-02 0. 1.04058278e-03 + 1.04058278e-03 2.08116546e-02 2.08116556e-03 1.15504690e-01 + 2.91363187e-02 0. 3.12174833e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 2.08116556e-03 0. 0. 0. 0. + 1.04058278e-03 0. 4.16233111e-03 0. 0. 0. 3.12174833e-03 0. + 1.04058273e-02 9.36524477e-03 2.08116556e-03 1.04058278e-03 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 3.12174833e-03 1.04058278e-03 1.04058278e-03 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 5.20291366e-03 6.24349667e-03 2.08116556e-03 + 1.04058278e-03 3.12174833e-03 0. 0. 0. 0. 2.08116556e-03 0. 0. + 1.04058278e-03 0. 0. 9.36524477e-03 6.24349667e-03 1.04058278e-03 + 7.28407968e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 0. 0. 0. 0. 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 0. 0. 1.04058278e-03 2.08116556e-03 2.08116556e-03 + 4.16233111e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 5.20291366e-03 9.36524477e-03 0. 1.04058278e-03 0. + 0. 0. 4.16233111e-03 0. 2.08116556e-03 0. 0. 0. 1.04058278e-03 + 3.12174833e-03 1.14464108e-02 1.04058278e-03 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. + 3.12174833e-03 4.16233111e-03 8.32466222e-03 4.37044762e-02 + 1.04058278e-03 1.66493244e-02 1.04058278e-03 2.08116556e-03 + 2.08116556e-03 3.12174833e-03 1.04058278e-03 4.16233111e-03 0. 0. + 0. 1.04058278e-03 2.08116556e-03 5.51508889e-02 4.89073917e-02 + 1.76899079e-02 0. 2.08116556e-03 2.08116556e-03 0. 3.12174833e-03 + 3.12174833e-03 1.04058278e-03 3.12174833e-03 0. 4.16233111e-03 + 2.08116556e-03 4.16233111e-03 5.09885550e-02 8.32466185e-02 + 1.97710730e-02 4.57856432e-02 0. 1.04058278e-03 9.36524477e-03 + 5.20291366e-03 5.20291366e-03 3.74609791e-02 0. 1.04058278e-03 0. + 0. 0. 0. 5.20291366e-03 3.95421460e-02 2.60145701e-02 + 1.76899079e-02 0. 2.08116556e-03 6.24349667e-03 1.04058278e-03 + 2.08116556e-03 1.14464108e-02 1.04058278e-03 0. 0. 0. + 3.53798158e-02 1.04058278e-03 3.53798158e-02 9.46930349e-02 0. 0. + 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 1.04058278e-03 4.16233111e-03 0. 8.32466222e-03 + 2.08116546e-02 2.08116556e-03 2.08116556e-03 0. 0. 0. 0. + 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 2.08116556e-03 4.16233111e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 1.04058273e-02 2.08116556e-03 0. 0. + 3.12174833e-03 0. 2.08116556e-03 0. 1.04058278e-03 0. 0. 0. + 3.32986489e-02 1.04058278e-03 1.45681594e-02 2.08116546e-02 + 2.08116556e-03 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. + 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. 1.04058273e-02 0. + 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 0. 2.08116556e-03 9.36524477e-03 0. 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 6.24349667e-03 0. 1.45681594e-02 0. + 3.12174833e-03 0. 4.16233111e-03 1.04058278e-03 1.04058273e-02 0. + 0. 0. 0. 0. 0. 0. 1.56087419e-02 2.08116556e-03 2.08116556e-03 0. + 0. 0. 0. 0. 1.04058278e-03 2.08116556e-03 0. 0. 0. 2.08116556e-03 + 1.04058278e-03 0. 2.80957352e-02 2.08116556e-03 6.03538007e-02 0. + 4.16233111e-03 0. 2.08116556e-03 0. 1.24869933e-02 0. 0. 0. 0. 0. + 0. 0. 3.64203975e-02 1.97710730e-02 1.56087419e-02 2.08116556e-03 + 8.32466222e-03 1.04058278e-03 4.16233111e-03 0. 1.45681594e-02 + 1.04058278e-03 5.20291366e-03 0. 2.08116556e-03 8.32466222e-03 + 6.24349667e-03 1.24869933e-02 1.00936532e-01 1.14464108e-02 + 1.45681594e-02 1.04058278e-03 3.12174833e-03 8.32466222e-03 + 1.04058278e-03 1.04058278e-03 2.28928216e-02 0. 0. 0. 0. + 1.04058278e-03 0. 4.16233111e-03 1.24869933e-02 1.45681594e-02 + 3.12174833e-03 0. 0. 2.08116556e-03 1.04058278e-03 0. + 3.12174833e-03 0. 1.04058278e-03 0. 0. 2.80957352e-02 0. + 7.18002096e-02 8.32466185e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 0. 0. 1.04058278e-03 0. + 0. 0. 0. 0. 0. 0. 1.24869933e-02 1.04058278e-03 1.14464108e-02 + 1.35275759e-02 1.14464108e-02 2.08116556e-03 0. 0. 1.04058278e-03 + 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 3.12174833e-03 2.08116556e-03 2.08116556e-03 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 7.28407968e-03 3.12174833e-03 0. 0. 1.04058278e-03 0. + 1.04058278e-03 3.12174833e-03 3.12174833e-03 0. 0. 0. + 1.35275759e-02 0. 7.28407968e-03 1.45681594e-02 0. 7.28407968e-03 + 0. 2.08116556e-03 0. 0. 0. 9.36524477e-03 0. 0. 0. 0. 0. + 2.08116556e-03 0. 2.08116556e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 7.28407968e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 7.28407968e-03 2.08116556e-03 + 4.26638946e-02 0. 1.66493244e-02 0. 3.12174833e-03 0. + 4.47450578e-02 0. 0. 0. 0. 0. 2.08116556e-03 0. 6.24349667e-03 + 1.04058278e-03 3.12174833e-03 0. 1.04058278e-03 0. 0. 0. + 3.12174833e-03 0. 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 + 1.76899079e-02 7.28407968e-03 1.54006258e-01 0. 2.60145701e-02 0. + 1.04058278e-03 0. 1.14464108e-02 0. 0. 0. 0. 0. 0. 3.12174833e-03 + 7.28407968e-03 7.28407968e-03 3.95421460e-02 0. 1.35275759e-02 0. + 1.04058278e-03 0. 1.87304895e-02 2.08116556e-03 6.24349667e-03 0. + 1.04058278e-03 7.28407968e-03 4.16233111e-03 1.35275759e-02 + 7.28407949e-02 1.76899079e-02 1.56087419e-02 2.08116556e-03 + 4.16233111e-03 2.08116556e-03 0. 1.04058278e-03 3.01769003e-02 0. + 0. 0. 0. 0. 0. 1.56087419e-02 7.70031288e-02 6.24349667e-03 + 1.14464108e-02 0. 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 + 0. 2.08116556e-03 2.08116556e-03 0. 1.04058278e-03 1.04058273e-02 + 2.08116556e-03 3.64203975e-02 5.61914705e-02 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 9.36524477e-03 0. 1.04058278e-03 0. 0. + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 8.32466222e-03 + 2.08116556e-03 6.24349667e-03 1.04058278e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 4.16233111e-03 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 1.35275759e-02 1.04058278e-03 0. 0. 2.08116556e-03 0. 0. 0. + 3.12174833e-03 0. 0. 0. 7.28407968e-03 0. 8.32466222e-03 + 3.12174833e-03 0. 2.08116556e-03 0. 3.12174833e-03 1.04058278e-03 + 1.04058278e-03 0. 4.68262248e-02 0. 0. 0. 0. 0. 0. 0. + 1.24869933e-02 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 1.24869933e-02 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 1.04058278e-03 1.97710730e-02 0. 1.14464108e-02 + 1.04058278e-03 1.04058278e-03 0. 7.28407968e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 5.20291366e-03 0. 2.08116556e-03 0. 0. + 2.08116556e-03 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 1.04058278e-03 1.76899079e-02 5.41103035e-02 + 0. 4.16233111e-03 0. 0. 2.08116556e-03 2.08116556e-03 0. 0. 0. 0. + 0. 1.04058278e-03 3.12174833e-03 1.14464108e-02 1.57128006e-01 + 1.27991676e-01 0. 2.08116556e-03 1.04058278e-03 0. 1.04058278e-03 + 3.12174833e-03 1.56087419e-02 7.28407968e-03 0. 2.08116556e-03 + 7.28407968e-03 5.20291366e-03 1.66493244e-02 3.53798158e-02 + 8.74089524e-02 4.37044762e-02 4.16233111e-03 3.12174833e-03 + 4.16233111e-03 3.12174833e-03 4.16233111e-03 8.32466222e-03 + 3.12174833e-03 1.04058278e-03 0. 0. 6.24349667e-03 5.20291366e-03 + 1.35275759e-02 3.53798158e-02 3.53798158e-02 5.20291366e-03 + 1.04058278e-03 2.08116556e-03 2.08116556e-03 0. 0. 0. + 1.04058273e-02 0. 1.04058278e-03 0. 1.66493244e-02 2.08116556e-03 + 5.93132190e-02 1.66493244e-02 0. 1.04058278e-03 0. 1.04058278e-03 + 2.08116556e-03 0. 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. + 2.08116556e-03 1.04058278e-03 2.08116556e-03 3.12174833e-03 + 2.08116556e-03 0. 3.12174833e-03 0. 2.08116556e-03 0. + 2.08116556e-03 0. 1.04058278e-03 3.12174833e-03 4.16233111e-03 0. + 1.66493244e-02 4.16233111e-03 7.28407968e-03 7.28407968e-03 0. + 2.08116556e-03 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. + 1.04058278e-03 0. 0. 2.08116556e-03 4.16233111e-03 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 4.16233111e-03 0. 0. 0. 0. 0. 2.08116556e-03 0. + 8.32466222e-03 4.16233111e-03 0. 3.12174833e-03 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 2.08116556e-03 + 9.36524477e-03 1.04058278e-03 0. 0. 2.08116556e-03 0. 0. 0. + 8.32466222e-03 2.08116556e-03 1.04058278e-03 1.04058278e-03 + 4.16233111e-03 1.04058278e-03 1.97710730e-02 9.36524477e-03 + 1.04058278e-03 4.16233111e-03 0. 3.12174833e-03 0. 0. 0. + 4.16233111e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 1.04058273e-02 + 2.08116556e-03 3.12174833e-03 0. 2.08116556e-03 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 2.08116556e-03 0. + 0. 4.16233111e-03 6.24349667e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 3.12174833e-03 0. 2.08116556e-03 1.14464108e-02 3.12174833e-03 + 9.36524477e-03 0. 6.24349667e-03 0. 0. 0. 2.08116556e-03 0. + 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 2.08116556e-03 + 7.28407968e-03 4.16233111e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 0. 1.04058278e-03 0. 2.08116556e-03 + 2.08116556e-03 1.14464108e-02 3.43392305e-02 0. 1.24869933e-02 + 2.08116556e-03 0. 2.08116556e-03 1.14464108e-02 1.04058278e-03 + 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 1.04058278e-03 + 8.32466222e-03 2.91363187e-02 2.80957352e-02 1.04058273e-02 0. + 6.24349667e-03 0. 0. 3.12174833e-03 1.04058278e-03 1.35275759e-02 + 1.35275759e-02 1.04058278e-03 5.20291366e-03 6.24349667e-03 + 6.24349667e-03 3.74609791e-02 9.05307010e-02 8.01248774e-02 + 3.64203975e-02 2.08116556e-03 7.28407968e-03 8.32466222e-03 + 2.08116556e-03 4.16233111e-03 1.56087419e-02 3.12174833e-03 + 2.08116556e-03 0. 1.04058278e-03 2.08116556e-03 3.12174833e-03 + 1.35275759e-02 3.32986489e-02 4.16233093e-02 3.12174833e-03 + 3.12174833e-03 3.12174833e-03 3.12174833e-03 1.04058278e-03 + 1.04058278e-03 2.08116556e-03 5.20291366e-03 0. 1.04058278e-03 0. + 9.36524477e-03 2.08116556e-03 2.60145701e-02 1.66493244e-02 + 3.12174833e-03 2.08116556e-03 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 9.36524477e-03 3.12174833e-03 1.04058278e-03 1.04058278e-03 0. 0. + 1.04058278e-03 0. 3.12174833e-03 0. 0. 0. 2.08116556e-03 0. + 7.28407968e-03 6.24349667e-03 1.04058273e-02 2.08116556e-03 + 1.04058278e-03 0. 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 0. 2.08116556e-03 1.04058278e-03 5.20291366e-03 + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 3.12174833e-03 3.12174833e-03 0. 0. 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 1.56087419e-02 3.12174833e-03 1.04058278e-03 0. 1.04058278e-03 0. + 1.04058278e-03 0. 7.28407968e-03 0. 0. 1.04058278e-03 + 2.08116556e-03 0. 8.32466222e-03 6.24349667e-03 3.12174833e-03 + 9.36524477e-03 1.04058278e-03 4.16233111e-03 0. 4.16233111e-03 0. + 1.24869933e-02 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 1.56087419e-02 2.08116556e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. + 2.08116556e-03 0. 0. 2.08116556e-03 0. 3.12174833e-03 + 9.36524477e-03 2.08116556e-03 1.04058278e-03 0. 0. 1.04058278e-03 + 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 8.32466222e-03 + 8.32466222e-03 1.24869933e-02 0. 0. 2.08116556e-03 1.04058278e-03 + 1.04058278e-03 5.20291366e-03 1.04058278e-03 0. 0. 0. + 1.04058278e-03 1.04058278e-03 2.08116556e-03 6.24349667e-03 + 4.16233111e-03 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 2.08116556e-03 + 3.12174833e-03 1.87304895e-02 1.76899079e-02 0. 8.32466222e-03 + 1.04058278e-03 4.16233111e-03 1.04058278e-03 1.35275759e-02 + 2.08116556e-03 5.20291366e-03 0. 3.12174833e-03 1.04058278e-03 + 1.04058278e-03 6.24349667e-03 3.12174838e-02 4.78668064e-02 + 2.08116546e-02 2.08116556e-03 7.28407968e-03 0. 0. 2.08116556e-03 + 8.32466222e-03 1.45681594e-02 7.28407968e-03 3.12174833e-03 + 9.36524477e-03 1.24869933e-02 9.36524477e-03 3.32986489e-02 + 9.67741981e-02 3.22580673e-02 4.16233093e-02 0. 8.32466222e-03 + 8.32466222e-03 1.04058278e-03 4.16233111e-03 2.08116546e-02 + 1.04058278e-03 1.04058278e-03 0. 0. 6.24349667e-03 0. + 7.28407968e-03 4.78668064e-02 3.32986489e-02 1.56087419e-02 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 2.08116556e-03 0. 0. 1.14464108e-02 0. 1.14464108e-02 + 1.66493244e-02 2.08116556e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 1.04058278e-03 7.28407968e-03 1.04058278e-03 0. + 0. 0. 0. 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. 3.12174833e-03 + 0. 7.28407968e-03 4.16233111e-03 4.16233111e-03 4.16233111e-03 0. + 1.04058278e-03 3.12174833e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. + 0. 0. 0. 2.08116556e-03 0. 5.20291366e-03 2.08116556e-03 0. 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 3.12174833e-03 2.18522381e-02 3.12174833e-03 0. 0. 0. 0. + 1.04058278e-03 0. 1.45681594e-02 0. 1.04058278e-03 0. + 4.16233111e-03 2.08116556e-03 6.24349667e-03 0. 1.04058278e-03 + 8.32466222e-03 0. 2.08116556e-03 0. 1.04058278e-03 0. + 5.20291366e-03 0. 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 + 7.28407968e-03 1.04058278e-03 3.12174833e-03 0. 2.08116556e-03 0. + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 1.14464108e-02 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 4.16233111e-03 2.08116556e-03 2.60145701e-02 0. 1.24869933e-02 + 1.04058278e-03 0. 1.04058278e-03 1.04058273e-02 0. 0. 0. 0. 0. 0. + 0. 1.35275759e-02 2.08116556e-03 5.20291366e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. + 3.12174833e-03 1.56087419e-02 8.42872038e-02 0. 9.36524477e-03 0. + 0. 2.08116556e-03 1.45681594e-02 0. 0. 0. 0. 0. 0. 8.32466222e-03 + 3.74609791e-02 8.63683671e-02 5.30697219e-02 1.04058278e-03 + 1.66493244e-02 1.04058278e-03 0. 1.04058278e-03 5.20291366e-03 + 2.08116546e-02 8.32466222e-03 1.04058278e-03 5.20291366e-03 + 7.28407968e-03 4.16233111e-03 2.80957352e-02 6.45161346e-02 + 1.97710730e-02 3.12174833e-03 0. 2.08116556e-03 1.04058273e-02 0. + 1.04058278e-03 7.28407968e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 4.16233111e-03 1.14464108e-02 0. 0. 0. 3.12174833e-03 0. + 2.08116556e-03 2.08116556e-03 2.08116556e-03 0. 0. 1.04058278e-03 + 5.20291366e-03 1.04058278e-03 1.45681594e-02 6.24349667e-03 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 8.32466222e-03 0. + 0. 0. 1.76899079e-02 0. 8.32466222e-03 6.24349667e-03 + 2.49739867e-02 1.04058278e-03 0. 1.04058278e-03 8.32466222e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 1.24869933e-02 1.04058278e-03 + 0. 0. 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. + 0. 0. 0. 0. 5.82726374e-02 2.08116556e-03 0. 0. 2.08116556e-03 0. + 2.08116556e-03 1.04058278e-03 4.78668064e-02 0. 0. 0. + 2.18522381e-02 1.04058278e-03 3.12174833e-03 0. 0. 6.24349667e-03 + 0. 3.12174833e-03 1.04058278e-03 0. 0. 1.04058273e-02 0. 0. 0. 0. + 0. 0. 0. 5.20291366e-03 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 7.28407968e-03 + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. + 5.20291366e-03 1.35275759e-02 2.70551518e-02 0. 2.08116546e-02 + 1.04058278e-03 1.04058278e-03 0. 1.14464108e-02 1.04058278e-03 0. + 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. + 0. 0. 5.20291366e-03 1.04058278e-03 2.08116556e-03 1.66493244e-02 + 6.24349676e-02 0. 2.18522381e-02 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 8.32466222e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 7.28407968e-03 1.21748187e-01 7.80437067e-02 + 0. 1.87304895e-02 1.04058278e-03 3.12174833e-03 1.04058278e-03 + 7.28407968e-03 3.95421460e-02 3.85015644e-02 0. 3.12174838e-02 + 9.36524477e-03 7.28407968e-03 8.32466222e-03 3.64203975e-02 + 3.43392305e-02 1.97710730e-02 0. 1.04058278e-03 3.12174833e-03 + 5.20291366e-03 4.16233111e-03 2.28928216e-02 1.04058278e-03 0. 0. + 0. 1.04058278e-03 0. 1.35275759e-02 2.60145701e-02 5.41103035e-02 + 1.56087419e-02 0. 1.04058278e-03 2.08116556e-03 0. 2.08116556e-03 + 0. 3.12174833e-03 1.04058278e-03 2.08116556e-03 0. 5.20291366e-03 + 0. 2.28928216e-02 1.24869933e-02 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 6.24349667e-03 2.08116556e-03 1.04058278e-03 0. 2.08116556e-03 0. + 2.08116556e-03 1.04058278e-03 0. 0. 1.04058278e-03 0. + 8.32466222e-03 1.04058278e-03 3.12174833e-03 4.16233111e-03 + 1.35275759e-02 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 3.12174833e-03 0. + 1.04058278e-03 0. 4.16233111e-03 1.04058278e-03 1.04058278e-03 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 1.04058278e-03 1.76899079e-02 2.08116556e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 1.45681594e-02 0. 0. 1.04058278e-03 + 9.36524477e-03 0. 7.28407968e-03 0. 2.08116556e-03 5.20291366e-03 + 0. 2.08116556e-03 0. 0. 0. 3.32986489e-02 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.35275759e-02 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 0. 6.24349667e-03 5.20291366e-03 8.32466222e-03 0. + 2.08116556e-03 1.04058278e-03 0. 0. 6.24349667e-03 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 2.08116556e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 3.12174833e-03 0. + 0. 0. 0. 0. 4.16233111e-03 2.18522381e-02 5.09885550e-02 0. + 5.20291366e-03 0. 2.08116556e-03 0. 6.24349667e-03 1.04058278e-03 + 0. 0. 0. 2.08116556e-03 2.08116556e-03 8.32466222e-03 + 2.49739867e-02 1.19667016e-01 8.01248774e-02 0. 4.16233111e-03 + 1.04058278e-03 2.08116556e-03 0. 3.12174833e-03 3.22580673e-02 + 1.56087419e-02 0. 7.28407968e-03 1.04058273e-02 3.12174833e-03 + 3.43392305e-02 6.86784610e-02 2.28928216e-02 1.14464108e-02 + 1.04058278e-03 7.28407968e-03 1.14464108e-02 0. 4.16233111e-03 + 4.57856432e-02 1.04058278e-03 0. 0. 0. 5.20291366e-03 + 1.04058278e-03 7.28407968e-03 1.56087419e-02 1.87304895e-02 + 8.32466222e-03 1.04058278e-03 1.04058278e-03 3.12174833e-03 0. + 1.04058278e-03 1.04058278e-03 6.24349667e-03 0. 0. 0. + 4.26638946e-02 1.04058278e-03 5.82726374e-02 4.16233093e-02 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 7.28407968e-03 0. 0. + 1.04058278e-03 2.39334032e-02 1.04058278e-03 1.45681594e-02 + 1.87304895e-02 2.08116556e-03 1.04058278e-03 0. 0. 2.08116556e-03 + 0. 1.04058278e-03 4.16233111e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 3.12174833e-03 0. 2.08116556e-03 1.04058278e-03 1.04058278e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 5.20291366e-03 0. 2.08116556e-03 0. 0. 0. 1.04058278e-03 0. + 7.59625435e-02 0. 1.04058278e-03 1.04058278e-03 5.61914705e-02 0. + 2.39334032e-02 1.66493244e-02 0. 4.16233111e-03 0. 6.24349667e-03 + 0. 0. 0. 8.42872038e-02 0. 1.04058278e-03 0. 0. 0. 0. 0. + 2.28928216e-02 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.35275759e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 1.56087419e-02 1.04058278e-03 + 1.04058273e-02 0. 6.24349667e-03 0. 1.04058278e-03 0. + 3.12174838e-02 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 9.36524477e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 5.20291366e-03 + 3.12174833e-03 3.85015644e-02 0. 8.32466222e-03 0. 0. 0. + 4.16233111e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.66493244e-02 + 9.36524477e-03 1.24869933e-02 0. 3.12174833e-03 1.04058278e-03 0. + 0. 3.12174833e-03 1.04058278e-03 1.04058278e-03 0. 5.20291366e-03 + 6.24349667e-03 3.12174833e-03 1.45681594e-02 4.57856432e-02 + 2.60145701e-02 2.49739867e-02 4.16233111e-03 2.08116556e-03 + 1.04058278e-03 0. 5.20291366e-03 1.24869933e-02 1.04058278e-03 0. + 0. 0. 3.12174833e-03 1.04058278e-03 4.16233111e-03 1.35275759e-02 + 2.18522381e-02 8.32466222e-03 0. 1.04058278e-03 3.12174833e-03 0. + 2.08116556e-03 4.16233111e-03 4.16233111e-03 1.04058278e-03 0. 0. + 4.99479733e-02 2.08116556e-03 1.51925087e-01 3.64203975e-02 + 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 2.08116556e-03 3.12174833e-03 0. 0. + 1.04058278e-03 0. 2.08116556e-03 0. 6.24349667e-03 0. 0. 0. + 3.64203975e-02 0. 3.85015644e-02 8.32466222e-03 4.16233111e-03 + 2.08116556e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 0. 9.36524477e-03 1.04058278e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 1.04058278e-03 0. 7.28407968e-03 1.04058278e-03 + 0. 0. 1.56087419e-02 0. 1.35275759e-02 0. 0. 4.16233111e-03 0. + 4.16233111e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 3.12174833e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 1.04058278e-03 + 4.16233111e-03 1.04058278e-03 3.95421460e-02 0. 3.32986489e-02 0. + 0. 0. 1.04058273e-02 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. + 1.66493244e-02 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 1.14464108e-02 + 6.24349667e-03 9.98959467e-02 0. 3.12174838e-02 0. 1.04058278e-03 + 0. 1.45681594e-02 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 1.66493244e-02 1.04058273e-02 1.76899079e-02 0. 8.32466222e-03 + 1.04058278e-03 0. 0. 3.12174833e-03 2.08116556e-03 7.28407968e-03 + 0. 2.08116556e-03 4.16233111e-03 3.12174833e-03 1.56087419e-02 + 4.99479733e-02 1.24869933e-02 2.70551518e-02 0. 0. 2.08116556e-03 + 0. 0. 4.16233111e-03 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. + 1.87304895e-02 1.38397515e-01 1.97710730e-02 2.49739867e-02 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 2.08116556e-03 2.08116556e-03 + 0. 0. 7.28407968e-03 1.04058278e-03 4.78668064e-02 4.78668064e-02 + 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 4.16233111e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. + 3.12174833e-03 0. 0. 0. 1.04058278e-03 0. 0. 5.20291366e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 9.36524477e-03 + 2.08116556e-03 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 4.16233111e-03 0. 0. 0. 1.04058278e-03 0. 5.20291366e-03 + 3.12174833e-03 1.04058278e-03 4.16233111e-03 0. 3.12174833e-03 0. + 2.08116556e-03 0. 8.32466222e-03 0. 0. 0. 0. 0. 0. 0. + 8.32466222e-03 0. 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 4.16233111e-03 8.32466222e-03 0. 1.04058273e-02 0. + 1.04058278e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 4.16233111e-03 1.04058278e-03 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 4.16233111e-03 1.45681594e-02 4.05827276e-02 0. + 6.24349667e-03 0. 0. 1.04058278e-03 4.16233111e-03 0. 0. 0. 0. 0. + 1.04058278e-03 3.12174833e-03 2.49739867e-02 1.88345477e-01 + 1.33194596e-01 0. 2.08116556e-03 1.04058278e-03 0. 1.04058278e-03 + 1.04058278e-03 5.20291366e-03 3.12174833e-03 1.04058278e-03 + 1.04058278e-03 9.36524477e-03 1.04058278e-03 1.97710730e-02 + 4.47450578e-02 5.72320521e-02 5.20291403e-02 1.04058278e-03 + 7.28407968e-03 5.20291366e-03 2.08116556e-03 3.12174833e-03 + 1.56087419e-02 0. 2.08116556e-03 0. 0. 8.32466222e-03 + 4.16233111e-03 1.76899079e-02 4.05827276e-02 3.74609791e-02 + 7.28407968e-03 2.08116556e-03 2.08116556e-03 3.12174833e-03 0. + 1.04058278e-03 5.20291366e-03 9.36524477e-03 3.12174833e-03 + 2.08116556e-03 1.04058278e-03 2.28928216e-02 1.04058278e-03 + 4.89073917e-02 2.39334032e-02 0. 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 1.04058273e-02 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 2.08116556e-03 0. 1.04058278e-03 2.08116556e-03 + 3.12174833e-03 0. 0. 0. 8.32466222e-03 0. 1.14464108e-02 + 8.32466222e-03 8.32466222e-03 3.12174833e-03 0. 3.12174833e-03 0. + 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. + 5.20291366e-03 2.08116556e-03 1.04058278e-03 1.04058278e-03 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 + 1.04058278e-03 9.36524477e-03 1.04058278e-03 1.04058278e-03 0. 0. + 0. 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 3.12174833e-03 + 2.08116556e-03 8.32466222e-03 4.16233111e-03 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 + 0. 8.32466222e-03 0. 2.08116556e-03 9.36524477e-03 0. + 4.16233111e-03 1.04058278e-03 0. 0. 2.08116556e-03 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.14464108e-02 6.24349667e-03 2.08116556e-03 + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 1.04058278e-03 2.08116556e-03 9.36524477e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 2.08116556e-03 2.08116556e-03 1.24869933e-02 7.28407968e-03 + 1.66493244e-02 0. 9.36524477e-03 0. 0. 0. 4.16233111e-03 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 3.12174833e-03 + 1.14464108e-02 4.16233111e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 2.08116556e-03 0. + 0. 4.16233111e-03 1.35275759e-02 2.18522381e-02 0. 1.04058273e-02 + 1.04058278e-03 1.04058278e-03 1.04058278e-03 1.14464108e-02 + 2.08116556e-03 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 2.08116556e-03 5.61914705e-02 2.08116546e-02 + 1.35275759e-02 3.12174833e-03 9.36524477e-03 1.04058278e-03 + 2.08116556e-03 2.08116556e-03 1.04058278e-03 5.20291366e-03 + 3.12174833e-03 0. 9.36524477e-03 8.32466222e-03 5.20291366e-03 + 3.12174838e-02 9.36524495e-02 8.01248774e-02 4.37044762e-02 + 4.16233111e-03 7.28407968e-03 1.35275759e-02 3.12174833e-03 + 1.24869933e-02 1.04058273e-02 2.08116556e-03 1.04058278e-03 0. + 3.12174833e-03 6.24349667e-03 2.08116556e-03 1.24869933e-02 + 2.80957352e-02 2.28928216e-02 4.16233111e-03 2.08116556e-03 0. 0. + 0. 1.04058278e-03 2.08116556e-03 8.32466222e-03 1.04058278e-03 0. + 1.04058278e-03 8.32466222e-03 1.04058278e-03 2.08116546e-02 + 1.45681594e-02 4.16233111e-03 3.12174833e-03 0. 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 1.04058278e-03 3.12174833e-03 0. 0. + 0. 0. 0. 0. 0. 3.12174833e-03 1.14464108e-02 1.04058278e-03 + 1.04058278e-03 3.12174833e-03 1.04058278e-03 0. 4.16233111e-03 + 1.04058278e-03 3.12174833e-03 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 9.36524477e-03 0. 9.36524477e-03 1.04058273e-02 + 9.36524477e-03 0. 0. 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. + 0. 0. 2.08116556e-03 0. 0. 1.04058278e-03 2.08116556e-03 0. 0. 0. + 0. 0. 0. 0. 3.12174833e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 7.28407968e-03 2.08116556e-03 1.04058278e-03 1.04058278e-03 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 2.08116556e-03 0. + 2.18522381e-02 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 0. + 0. 0. 1.14464108e-02 0. 2.08116556e-03 1.04058278e-03 + 9.36524477e-03 0. 1.24869933e-02 5.20291366e-03 6.24349667e-03 + 8.32466222e-03 0. 2.08116556e-03 2.08116556e-03 2.08116556e-03 0. + 8.32466222e-03 0. 1.04058278e-03 0. 0. 0. 0. 2.08116556e-03 + 1.56087419e-02 2.08116556e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. + 1.04058278e-03 8.32466222e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. + 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 5.20291366e-03 + 8.32466222e-03 1.04058273e-02 0. 8.32466222e-03 0. 2.08116556e-03 + 0. 8.32466222e-03 0. 1.04058278e-03 0. 2.08116556e-03 + 2.08116556e-03 1.04058278e-03 2.08116556e-03 1.14464108e-02 + 5.20291366e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 4.16233111e-03 3.12174833e-03 0. 4.16233111e-03 + 1.14464108e-02 1.14464108e-02 0. 1.24869933e-02 3.12174833e-03 + 2.08116556e-03 1.04058278e-03 1.04058273e-02 1.04058278e-03 + 1.04058278e-03 0. 2.08116556e-03 2.08116556e-03 2.08116556e-03 + 2.08116556e-03 1.97710730e-02 2.70551518e-02 9.36524477e-03 + 3.12174833e-03 6.24349667e-03 1.04058278e-03 0. 3.12174833e-03 + 4.16233111e-03 2.49739867e-02 7.28407968e-03 5.20291366e-03 + 1.35275759e-02 6.24349667e-03 7.28407968e-03 2.70551518e-02 + 1.15504690e-01 2.91363187e-02 1.35275759e-02 2.08116556e-03 + 3.12174833e-03 5.20291366e-03 0. 5.20291366e-03 3.12174833e-03 0. + 0. 0. 0. 5.20291366e-03 0. 3.12174833e-03 4.16233111e-03 + 1.87304895e-02 4.16233111e-03 0. 0. 3.12174833e-03 0. + 1.04058278e-03 1.04058278e-03 4.16233111e-03 0. 0. 0. + 1.87304895e-02 1.04058278e-03 2.91363187e-02 8.32466222e-03 + 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 6.24349667e-03 0. 0. 0. 2.08116556e-03 0. 2.08116556e-03 0. + 3.12174833e-03 0. 0. 1.04058278e-03 1.45681594e-02 0. + 6.24349667e-03 7.28407968e-03 1.56087419e-02 2.08116556e-03 0. 0. + 2.08116556e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 7.28407968e-03 2.08116556e-03 + 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 9.36524477e-03 2.08116556e-03 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 8.32466222e-03 0. 1.04058278e-03 + 2.08116556e-03 7.28407968e-03 0. 5.20291366e-03 5.20291366e-03 0. + 5.20291366e-03 0. 3.12174833e-03 1.04058278e-03 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 3.12174833e-03 3.12174833e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 3.12174833e-03 0. 0. 0. + 0. 3.12174833e-03 0. 1.04058278e-03 7.28407968e-03 6.24349667e-03 + 4.05827276e-02 0. 5.20291403e-02 0. 0. 0. 6.24349667e-03 + 1.04058278e-03 0. 0. 2.08116556e-03 0. 0. 1.04058278e-03 + 5.20291366e-03 1.04058278e-03 3.12174833e-03 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 1.04058278e-03 + 1.14464108e-02 2.39334032e-01 0. 3.32986489e-02 2.08116556e-03 + 2.08116556e-03 0. 1.35275759e-02 0. 0. 0. 2.08116556e-03 + 2.08116556e-03 1.04058278e-03 1.04058278e-03 1.35275759e-02 + 1.56087419e-02 5.51508889e-02 0. 1.56087419e-02 0. 3.12174833e-03 + 0. 1.66493244e-02 6.24349667e-03 7.28407968e-03 0. 1.66493244e-02 + 1.04058273e-02 7.28407968e-03 1.14464108e-02 5.93132190e-02 + 3.12174833e-03 1.35275759e-02 0. 3.12174833e-03 6.24349667e-03 + 2.08116556e-03 1.04058278e-03 2.70551518e-02 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.24869933e-02 1.14464108e-02 3.12174833e-03 + 0. 0. 2.08116556e-03 0. 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. + 1.14464108e-02 2.08116556e-03 5.20291366e-03 4.57856432e-02 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 2.08116556e-03 0. 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 0. 0. + 0. 3.12174833e-03 0. 0. 5.20291366e-03 7.28407968e-03 0. 0. 0. + 6.24349667e-03 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. + 4.16233111e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. + 0. 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 3.43392305e-02 3.12174833e-03 1.04058278e-03 1.04058278e-03 + 3.12174833e-03 0. 0. 1.04058278e-03 1.35275759e-02 2.08116556e-03 + 0. 0. 1.04058273e-02 0. 6.24349667e-03 7.28407968e-03 0. + 5.20291366e-03 0. 0. 0. 0. 0. 1.97710730e-02 0. 0. 0. 0. 0. 0. 0. + 1.14464108e-02 0. 2.08116556e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 0. 0. 0. 1.04058278e-03 2.08116556e-03 0. 1.04058273e-02 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 3.12174833e-03 3.85015644e-02 0. 1.04058278e-03 0. 1.04058278e-03 + 0. 3.01769003e-02 0. 0. 0. 0. 0. 0. 0. 9.36524477e-03 + 1.04058278e-03 4.16233111e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. + 8.32466222e-03 2.08116556e-03 1.56087419e-02 0. 2.08116556e-03 0. + 1.04058278e-03 0. 1.14464108e-02 0. 0. 0. 0. 0. 0. 0. + 8.32466222e-03 1.29032269e-01 1.52965665e-01 0. 1.04058273e-02 + 3.12174833e-03 0. 1.04058278e-03 2.18522381e-02 3.53798158e-02 + 2.28928216e-02 0. 3.12174833e-03 1.45681594e-02 1.35275759e-02 + 4.16233111e-03 1.09261192e-01 1.76899079e-02 1.04058273e-02 0. + 1.04058278e-03 0. 2.08116556e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 2.91363187e-02 1.87304895e-02 + 1.04058278e-03 0. 0. 2.08116556e-03 0. 2.08116556e-03 0. 0. 0. 0. + 0. 0. 0. 7.28407968e-03 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 3.12174833e-03 2.08116556e-03 0. + 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. + 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 4.16233111e-03 3.12174833e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 6.55567124e-02 2.08116556e-03 0. 0. 0. 0. 0. 0. + 4.16233111e-03 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 2.08116556e-03 0. 0. + 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 6.24349667e-03 9.36524477e-03 2.18522381e-02 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.35275759e-02 3.96462053e-01 + 1.67533830e-01 1.04058278e-03 1.04058278e-03 2.08116556e-03 + 4.16233111e-03 1.04058278e-03 2.08116556e-03 6.03538007e-02 + 3.01769003e-02 0. 0. 1.24869933e-02 1.76899079e-02 8.32466222e-03 + 2.39334032e-02 1.56087419e-02 1.87304895e-02 0. 6.24349667e-03 + 7.28407968e-03 2.08116556e-03 1.04058273e-02 3.22580673e-02 0. 0. + 0. 0. 3.12174833e-03 0. 9.36524477e-03 4.68262248e-02 + 1.66493244e-02 4.16233111e-03 0. 1.04058278e-03 0. 0. 0. + 1.04058278e-03 2.08116556e-03 2.08116556e-03 0. 0. 2.60145701e-02 + 1.04058278e-03 2.28928216e-02 3.43392305e-02 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058273e-02 0. 0. 1.04058278e-03 1.14464108e-02 0. + 1.35275759e-02 1.04058273e-02 6.24349667e-03 1.04058278e-03 0. 0. + 3.12174833e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 0. 0. 6.24349667e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 1.04058278e-03 2.39334032e-02 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 0. 1.04058278e-03 9.26118642e-02 + 1.04058278e-03 1.04058278e-03 0. 1.87304895e-02 0. 1.45681594e-02 + 9.36524477e-03 1.04058278e-03 6.24349667e-03 0. 1.04058273e-02 0. + 0. 0. 6.24349676e-02 0. 0. 0. 0. 0. 0. 0. 3.01769003e-02 + 1.04058278e-03 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. + 1.04058278e-03 0. 1.04058278e-03 0. 1.04058278e-03 2.08116556e-03 + 0. 1.04058278e-03 1.76899079e-02 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 8.32466222e-03 2.08116556e-03 + 1.97710730e-02 0. 1.97710730e-02 0. 0. 1.04058278e-03 + 2.28928216e-02 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. + 8.32466222e-03 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 6.24349667e-03 + 1.04058273e-02 4.99479733e-02 0. 7.28407968e-03 0. 0. + 1.04058278e-03 1.35275759e-02 0. 1.04058278e-03 0. 0. + 1.04058278e-03 1.04058278e-03 2.08116556e-03 1.76899079e-02 + 3.43392305e-02 1.97710730e-02 0. 8.32466222e-03 0. 0. 0. + 6.24349667e-03 1.24869933e-02 4.16233111e-03 2.08116556e-03 + 1.04058278e-03 0. 2.08116556e-03 1.04058273e-02 5.72320521e-02 + 2.39334032e-02 1.45681594e-02 2.08116556e-03 1.14464108e-02 + 6.24349667e-03 0. 1.14464108e-02 4.16233111e-03 1.04058278e-03 + 1.04058278e-03 0. 0. 3.12174833e-03 0. 9.36524477e-03 + 1.45681594e-02 2.08116546e-02 5.20291366e-03 3.12174833e-03 + 1.04058278e-03 4.16233111e-03 0. 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 1.04058278e-03 0. 0. 5.93132190e-02 1.04058278e-03 + 1.97710723e-01 2.18522381e-02 5.20291366e-03 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 6.24349667e-03 0. 0. 1.04058278e-03 2.08116556e-03 0. + 1.04058278e-03 0. 2.08116556e-03 0. 0. 1.04058278e-03 + 2.70551518e-02 0. 5.20291403e-02 4.16233111e-03 2.08116556e-03 + 4.16233111e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. + 4.16233111e-03 6.24349667e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 4.16233111e-03 3.12174833e-03 0. 0. 0. 0. 0. 0. + 6.24349667e-03 1.04058278e-03 0. 0. 6.24349667e-03 0. + 7.28407968e-03 3.12174833e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 1.04058278e-03 0. 5.20291366e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 2.08116556e-03 0. 1.04058278e-03 5.20291366e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 6.24349667e-03 0. 3.32986489e-02 0. + 1.97710730e-02 0. 0. 0. 9.36524477e-03 0. 0. 0. 0. 1.04058278e-03 + 2.08116556e-03 0. 6.24349667e-03 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 2.08116556e-03 1.04058273e-02 1.36316344e-01 0. 2.08116546e-02 0. + 0. 0. 2.08116556e-03 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 3.12174833e-03 0. 9.36524477e-03 3.12174833e-03 2.08116546e-02 0. + 1.04058278e-03 0. 0. 0. 2.08116556e-03 8.32466222e-03 + 1.14464108e-02 0. 3.12174833e-03 1.45681594e-02 6.24349667e-03 + 1.66493244e-02 3.95421460e-02 + <_ type_id="opencv-matrix"> + 1 + 16384 +
f
+ + 4.16233111e-03 1.35275759e-02 0. 6.24349667e-03 5.20291366e-03 + 1.04058278e-03 3.12174833e-03 1.04058273e-02 0. 0. 0. 0. + 1.04058278e-03 0. 1.14464108e-02 5.41103035e-02 1.04058273e-02 + 1.45681594e-02 0. 1.04058278e-03 2.08116556e-03 0. 0. + 4.16233111e-03 2.08116556e-03 0. 0. 0. 2.91363187e-02 + 2.08116556e-03 1.34235173e-01 1.07180029e-01 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 0. 0. 0. 4.16233111e-03 0. 0. 0. 2.70551518e-02 0. 3.43392305e-02 + 7.28407968e-03 3.12174833e-03 2.08116556e-03 0. 3.12174833e-03 + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.14464108e-02 3.12174833e-03 0. 0. 1.04058278e-03 0. + 1.04058278e-03 0. 7.28407968e-03 0. 0. 0. 3.12174838e-02 + 1.04058278e-03 5.20291366e-03 6.24349667e-03 0. 3.12174833e-03 0. + 2.08116556e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 7.28407968e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 2.91363187e-02 0. 1.35275759e-02 0. 2.08116556e-03 0. + 1.35275759e-02 0. 0. 0. 0. 0. 0. 0. 8.32466222e-03 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. + 0. 0. 0. 0. 6.24349667e-03 3.12174833e-03 8.01248774e-02 0. + 2.70551518e-02 0. 0. 0. 1.45681594e-02 0. 1.04058278e-03 0. 0. 0. + 0. 0. 5.20291366e-03 1.24869933e-02 5.20291403e-02 0. + 1.04058273e-02 1.04058278e-03 0. 0. 1.87304895e-02 8.32466222e-03 + 4.16233111e-03 0. 2.08116556e-03 1.04058273e-02 1.14464108e-02 + 3.12174833e-03 6.03538007e-02 2.08116556e-03 3.12174833e-03 0. 0. + 8.32466222e-03 0. 0. 5.20291366e-03 0. 0. 0. 0. 2.08116556e-03 0. + 5.20291366e-03 1.24869933e-02 1.24869933e-02 8.32466222e-03 + 1.04058278e-03 0. 0. 0. 0. 2.08116556e-03 2.08116556e-03 + 1.04058278e-03 0. 0. 1.14464108e-02 0. 2.49739867e-02 + 2.49739867e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 5.20291366e-03 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. + 0. 0. 9.36524477e-03 1.04058278e-03 8.32466222e-03 7.28407968e-03 + 9.36524477e-03 0. 0. 1.04058278e-03 3.12174833e-03 0. + 1.04058278e-03 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 0. + 0. 1.04058278e-03 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 4.26638946e-02 5.20291366e-03 0. 0. + 3.12174833e-03 0. 0. 2.08116556e-03 1.66493244e-02 1.04058278e-03 + 0. 0. 4.47450578e-02 0. 1.24869933e-02 8.32466222e-03 0. + 2.08116556e-03 0. 0. 0. 0. 0. 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. + 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 3.12174833e-03 1.66493244e-02 0. 6.24349667e-03 0. 1.04058278e-03 + 0. 1.45681594e-02 0. 0. 0. 0. 0. 0. 0. 5.20291366e-03 0. + 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 6.24349667e-03 1.97710730e-02 5.93132190e-02 0. + 1.87304895e-02 2.08116556e-03 4.16233111e-03 0. 1.04058273e-02 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 2.08116556e-03 + 5.20291366e-03 8.84495378e-02 1.82101980e-01 0. 1.35275759e-02 + 1.04058278e-03 2.08116556e-03 0. 1.14464108e-02 1.56087419e-02 + 2.18522381e-02 0. 9.36524477e-03 2.49739867e-02 2.08116546e-02 + 1.56087419e-02 6.76378831e-02 1.76899079e-02 1.24869933e-02 + 2.08116556e-03 2.08116556e-03 1.66493244e-02 4.16233111e-03 + 3.12174833e-03 1.14464108e-02 0. 0. 0. 0. 2.08116556e-03 0. + 2.08116556e-03 2.08116556e-03 2.39334032e-02 1.14464108e-02 0. + 1.04058278e-03 3.12174833e-03 0. 0. 4.16233111e-03 1.04058278e-03 + 0. 1.04058278e-03 0. 2.91363187e-02 6.24349667e-03 1.24869933e-02 + 3.43392305e-02 0. 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 0. + 0. 0. 0. 0. 0. 0. 0. 6.24349667e-03 2.08116556e-03 0. 0. + 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. + 1.76899079e-02 0. 5.20291366e-03 1.24869933e-02 9.36524477e-03 + 2.08116556e-03 0. 1.04058278e-03 6.24349667e-03 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 6.24349667e-03 + 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 3.12174833e-03 0. 2.08116556e-03 2.08116556e-03 3.12174833e-03 + 2.08116556e-03 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. + 4.57856432e-02 6.24349667e-03 1.04058278e-03 0. 2.08116556e-03 0. + 2.08116556e-03 2.08116556e-03 7.28407968e-03 0. 0. 0. + 4.78668064e-02 4.16233111e-03 1.04058273e-02 2.08116546e-02 0. 0. + 1.04058278e-03 2.08116556e-03 0. 0. 0. 4.16233111e-03 0. 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 2.08116556e-03 + 0. 1.14464108e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 1.04058278e-03 9.36524477e-03 3.12174833e-03 + 2.39334032e-02 0. 1.24869933e-02 1.04058278e-03 1.04058278e-03 0. + 1.35275759e-02 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 0. + 3.12174833e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 0. 0. 2.08116556e-03 3.12174833e-03 0. + 8.32466222e-03 4.16233111e-03 1.24869933e-02 0. 6.24349667e-03 + 1.04058278e-03 0. 1.04058278e-03 3.12174833e-03 0. 1.04058278e-03 + 0. 0. 1.04058278e-03 0. 0. 6.24349667e-03 2.39334032e-02 + 6.24349676e-02 0. 1.35275759e-02 3.12174833e-03 2.08116556e-03 0. + 1.35275759e-02 2.18522381e-02 1.66493244e-02 0. 8.32466222e-03 + 1.45681594e-02 5.41103035e-02 9.36524477e-03 1.49843916e-01 + 2.70551518e-02 8.32466222e-03 1.04058278e-03 3.12174833e-03 + 1.45681594e-02 3.12174833e-03 3.12174833e-03 1.66493244e-02 + 1.04058278e-03 0. 0. 0. 3.12174833e-03 0. 1.04058278e-03 + 9.36524477e-03 9.36524477e-03 5.20291366e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 1.04058278e-03 4.16233111e-03 0. 0. 0. + 1.87304895e-02 4.16233111e-03 1.87304895e-02 3.74609791e-02 + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. 1.04058273e-02 1.04058278e-03 + 0. 1.04058278e-03 3.01769003e-02 2.08116556e-03 1.24869933e-02 + 6.24349667e-03 1.76899079e-02 0. 0. 0. 8.32466222e-03 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 2.08116556e-03 1.04058278e-03 1.04058278e-03 1.04058278e-03 + 7.28407968e-03 1.04058278e-03 0. 0. 2.08116556e-03 0. 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 3.01769003e-02 + 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 4.16233093e-02 2.08116556e-03 0. 0. 5.41103035e-02 1.04058278e-03 + 1.87304895e-02 9.36524477e-03 1.04058278e-03 8.32466222e-03 0. + 3.12174833e-03 0. 2.08116556e-03 0. 3.43392305e-02 0. 0. 0. 0. + 1.04058278e-03 0. 0. 8.32466222e-03 0. 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 1.35275759e-02 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 1.56087419e-02 1.04058273e-02 + 2.08116546e-02 0. 2.08116546e-02 1.04058278e-03 2.08116556e-03 0. + 2.08116546e-02 0. 0. 0. 0. 1.04058278e-03 0. 0. 2.08116556e-03 + 2.08116556e-03 3.12174833e-03 0. 1.04058278e-03 0. 0. 0. + 3.12174833e-03 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. + 1.66493244e-02 8.32466222e-03 1.45681594e-02 2.08116556e-03 + 3.12174833e-03 0. 0. 0. 1.04058273e-02 0. 1.04058278e-03 0. 0. 0. + 0. 0. 1.04058278e-03 1.87304895e-02 3.22580673e-02 1.04058278e-03 + 1.45681594e-02 1.04058278e-03 1.04058278e-03 0. 7.28407968e-03 + 2.28928216e-02 1.35275759e-02 0. 1.87304895e-02 3.12174838e-02 + 1.97710730e-02 1.04058273e-02 8.74089524e-02 2.18522381e-02 + 5.20291366e-03 0. 1.04058278e-03 1.35275759e-02 1.04058278e-03 + 2.08116556e-03 2.49739867e-02 0. 0. 0. 0. 3.12174833e-03 + 2.08116556e-03 5.20291366e-03 2.08116546e-02 1.45681594e-02 + 3.12174833e-03 0. 0. 5.20291366e-03 0. 0. 6.24349667e-03 + 4.16233111e-03 0. 0. 0. 4.57856432e-02 3.12174833e-03 + 3.74609791e-02 8.22060406e-02 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 8.32466222e-03 1.04058278e-03 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. + 1.56087419e-02 0. 8.32466222e-03 1.45681594e-02 1.45681594e-02 + 3.12174833e-03 0. 0. 6.24349667e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 + 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 + 5.20291366e-03 0. 2.08116556e-03 4.16233111e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.49739867e-02 2.08116556e-03 + 1.04058278e-03 1.04058278e-03 2.08116556e-03 0. 0. 2.08116556e-03 + 1.97710730e-02 2.08116556e-03 3.12174833e-03 2.08116556e-03 + 5.41103035e-02 4.16233111e-03 1.04058273e-02 2.08116546e-02 0. + 3.12174833e-03 0. 0. 0. 1.04058278e-03 0. 3.64203975e-02 0. 0. 0. + 0. 0. 0. 0. 1.24869933e-02 1.04058278e-03 0. 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.24869933e-02 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 2.08116556e-03 0. 1.04058273e-02 + 2.08116556e-03 1.04058273e-02 0. 3.12174833e-03 1.04058278e-03 + 2.08116556e-03 0. 1.56087419e-02 0. 1.04058278e-03 0. 0. 0. 0. 0. + 3.12174833e-03 0. 4.16233111e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 0. 0. 0. 0. 9.36524477e-03 0. 1.45681594e-02 1.04058278e-03 + 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 5.20291366e-03 3.12174833e-03 + 2.08116546e-02 0. 8.32466222e-03 0. 2.08116556e-03 0. + 6.24349676e-02 1.14464108e-02 6.24349667e-03 2.08116556e-03 + 6.24349667e-03 1.14464108e-02 2.80957352e-02 5.20291366e-03 + 1.17585853e-01 1.04058278e-03 9.36524477e-03 0. 1.04058278e-03 + 6.24349667e-03 1.04058278e-03 0. 1.97710730e-02 0. 0. 0. 0. + 1.04058278e-03 2.08116556e-03 2.08116556e-03 3.95421460e-02 + 1.56087419e-02 7.28407968e-03 0. 2.08116556e-03 0. 0. 0. + 1.04058278e-03 3.12174833e-03 0. 0. 0. 1.76899079e-02 + 2.08116556e-03 3.64203975e-02 7.59625435e-02 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 1.04058273e-02 1.04058278e-03 + 7.28407968e-03 8.32466222e-03 5.20291366e-03 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 0. 0. 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 3.53798158e-02 + 3.12174833e-03 0. 0. 0. 0. 0. 1.04058278e-03 1.87304895e-02 0. 0. + 0. 2.60145701e-02 2.08116556e-03 7.28407968e-03 1.56087419e-02 0. + 0. 0. 0. 0. 0. 0. 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. + 1.97710730e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.35275759e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 6.24349667e-03 0. + 9.36524477e-03 0. 1.04058278e-03 0. 2.80957352e-02 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.14464108e-02 0. 3.12174833e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. + 6.24349667e-03 7.28407968e-03 3.32986489e-02 0. 3.12174833e-03 0. + 1.04058278e-03 0. 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. + 5.20291366e-03 1.73777327e-01 9.15712863e-02 0. 6.24349667e-03 + 1.04058278e-03 0. 0. 1.35275759e-02 3.12174838e-02 9.36524477e-03 + 0. 0. 7.28407968e-03 1.45681594e-02 1.04058273e-02 6.97190464e-02 + 2.08116546e-02 1.04058273e-02 1.04058278e-03 1.04058278e-03 + 1.35275759e-02 3.12174833e-03 0. 2.80957352e-02 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 6.03538007e-02 + 1.97710730e-02 8.32466222e-03 0. 0. 1.04058278e-03 1.04058278e-03 + 0. 1.04058278e-03 6.24349667e-03 2.08116556e-03 0. 0. + 3.85015644e-02 4.16233111e-03 1.66493244e-02 3.95421460e-02 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 4.16233111e-03 0. 0. 0. 0. 0. 0. + 0. 0. 7.28407968e-03 0. 0. 0. 1.04058278e-03 0. 0. 2.08116556e-03 + 4.16233111e-03 0. 0. 0. 2.80957352e-02 4.16233111e-03 + 2.18522381e-02 1.87304895e-02 4.16233111e-03 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 3.12174833e-03 0. 0. 1.04058278e-03 2.08116556e-03 2.08116556e-03 + 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 3.43392305e-02 1.04058278e-03 1.04058278e-03 2.08116556e-03 + 3.12174833e-03 0. 1.04058278e-03 2.08116556e-03 1.14464108e-02 0. + 0. 0. 3.01769003e-02 0. 2.08116546e-02 1.14464108e-02 0. + 2.08116556e-03 0. 1.04058278e-03 0. 1.04058278e-03 0. + 8.32466222e-03 0. 0. 0. 0. 0. 4.16233111e-03 0. 1.66493244e-02 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 1.24869933e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 2.08116556e-03 1.14464108e-02 0. 3.12174833e-03 0. 0. 0. + 1.66493244e-02 0. 0. 0. 0. 0. 1.04058278e-03 0. 6.24349667e-03 + 1.04058278e-03 3.12174833e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. + 0. 0. 2.08116556e-03 3.12174833e-03 0. 1.04058273e-02 + 5.20291366e-03 1.04058273e-02 0. 0. 0. 1.04058278e-03 0. + 9.36524477e-03 0. 0. 0. 0. 0. 0. 0. 4.16233111e-03 1.11342356e-01 + 1.14464108e-02 0. 3.12174833e-03 1.04058278e-03 1.04058278e-03 + 3.12174833e-03 1.76899079e-02 2.08116546e-02 9.36524477e-03 0. + 4.16233111e-03 2.70551518e-02 9.36524477e-03 1.35275759e-02 + 1.14464104e-01 3.22580673e-02 7.28407968e-03 2.08116556e-03 + 6.24349667e-03 1.14464108e-02 0. 4.16233111e-03 1.35275759e-02 + 1.04058278e-03 0. 0. 0. 2.08116556e-03 1.04058278e-03 + 4.16233111e-03 4.37044762e-02 1.14464108e-02 4.16233111e-03 0. 0. + 2.08116556e-03 0. 1.04058278e-03 2.08116556e-03 3.12174833e-03 + 1.04058278e-03 0. 0. 3.22580673e-02 1.04058278e-03 3.01769003e-02 + 1.76899079e-02 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 4.16233111e-03 + 2.08116556e-03 1.04058278e-03 0. 1.04058278e-03 0. 1.04058278e-03 + 0. 3.12174833e-03 1.04058278e-03 0. 0. 1.87304895e-02 + 2.08116556e-03 3.74609791e-02 8.32466222e-03 1.56087419e-02 + 4.16233111e-03 1.04058278e-03 2.08116556e-03 3.12174833e-03 0. 0. + 3.12174833e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 + 0. 5.20291366e-03 3.12174833e-03 0. 2.08116556e-03 1.04058278e-03 + 0. 0. 3.12174833e-03 0. 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 3.74609791e-02 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 4.16233111e-03 0. 0. 0. 1.35275759e-02 0. 0. 0. + 1.66493244e-02 0. 4.16233111e-03 5.20291366e-03 2.08116556e-03 + 6.24349667e-03 0. 1.04058278e-03 0. 2.08116556e-03 0. + 1.04058273e-02 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 6.24349667e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. + 3.12174833e-03 0. 0. 0. 0. 2.08116556e-03 0. 0. 1.14464108e-02 0. + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. + 3.12174833e-03 7.28407968e-03 3.85015644e-02 0. 2.28928216e-02 0. + 2.08116556e-03 0. 1.97710730e-02 1.04058278e-03 1.04058278e-03 0. + 0. 0. 3.12174833e-03 0. 9.36524477e-03 1.04058278e-03 + 1.04058278e-03 0. 2.08116556e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. 0. 6.24349667e-03 + 9.36524477e-03 1.35275759e-02 0. 1.56087419e-02 0. 0. + 2.08116556e-03 9.36524477e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 8.32466222e-03 4.26638946e-02 5.93132190e-02 1.04058278e-03 + 1.87304895e-02 3.12174833e-03 0. 1.04058278e-03 1.45681594e-02 + 1.97710730e-02 1.35275759e-02 0. 1.04058273e-02 1.04058273e-02 + 1.56087419e-02 4.16233111e-03 9.67741981e-02 6.24349667e-03 + 1.35275759e-02 0. 4.16233111e-03 4.16233111e-03 1.04058278e-03 + 1.04058278e-03 1.45681594e-02 0. 0. 0. 0. 1.04058278e-03 0. + 1.76899079e-02 6.03538007e-02 1.04058273e-02 8.32466222e-03 0. + 2.08116556e-03 2.08116556e-03 0. 0. 3.12174833e-03 3.12174833e-03 + 0. 1.04058278e-03 1.04058278e-03 2.49739867e-02 5.20291366e-03 + 1.59209162e-01 1.03017695e-01 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 2.08116556e-03 0. 0. 0. 0. 2.08116556e-03 0. 4.16233111e-03 + 6.24349667e-03 0. 2.08116556e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 1.56087419e-02 2.08116556e-03 0. 0. 0. 0. 0. + 1.04058278e-03 3.12174833e-03 0. 0. 0. 4.16233111e-03 0. + 4.16233111e-03 5.20291366e-03 0. 3.12174833e-03 0. 0. 0. 0. 0. + 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 0. 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 1.04058278e-03 0. 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.14464108e-02 0. 8.32466222e-03 0. + 0. 1.04058278e-03 1.45681594e-02 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.14464108e-02 0. 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.24869933e-02 1.35275759e-02 4.37044762e-02 0. + 5.20291366e-03 0. 1.04058278e-03 0. 1.45681594e-02 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 1.04058273e-02 7.59625435e-02 + 1.44641012e-01 0. 3.12174833e-03 0. 0. 0. 5.20291366e-03 + 2.08116556e-03 3.12174833e-03 0. 0. 2.08116556e-03 9.36524477e-03 + 1.04058273e-02 5.82726374e-02 1.35275759e-02 8.32466222e-03 0. 0. + 3.12174833e-03 1.04058278e-03 0. 4.16233111e-03 0. 0. 0. 0. 0. + 1.04058278e-03 6.24349667e-03 1.76899079e-02 1.14464108e-02 + 4.16233111e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. + 0. 1.14464108e-02 2.08116556e-03 2.18522381e-02 1.76899079e-02 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 0. 1.04058278e-03 + 1.04058278e-03 1.45681594e-02 2.08116556e-03 0. 0. 3.12174833e-03 + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 6.24349667e-03 + 2.08116556e-03 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 4.05827276e-02 0. 1.04058278e-03 + 0. 2.08116556e-03 0. 2.08116556e-03 1.04058278e-03 1.56087419e-02 + 1.04058278e-03 0. 0. 2.08116546e-02 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. + 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. 6.24349667e-03 2.08116556e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 3.12174833e-03 3.12174833e-03 3.22580673e-02 0. 1.76899079e-02 0. + 3.12174833e-03 1.04058278e-03 2.39334032e-02 0. 0. 0. 0. 0. + 2.08116556e-03 0. 2.08116556e-03 1.04058278e-03 0. 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 1.56087419e-02 + 6.76378831e-02 0. 2.08116546e-02 0. 2.08116556e-03 1.04058278e-03 + 1.14464108e-02 0. 0. 0. 0. 1.04058278e-03 0. 2.08116556e-03 + 1.87304895e-02 8.32466185e-02 1.71696156e-01 0. 1.14464108e-02 + 3.12174833e-03 1.04058278e-03 1.04058278e-03 1.76899079e-02 + 2.18522381e-02 2.80957352e-02 0. 7.28407968e-03 1.24869933e-02 + 1.24869933e-02 1.45681594e-02 1.00936532e-01 4.89073917e-02 + 1.87304895e-02 3.12174833e-03 3.12174833e-03 1.04058273e-02 0. + 4.16233111e-03 8.32466222e-03 0. 1.04058278e-03 1.04058278e-03 0. + 1.04058278e-03 0. 3.12174833e-03 3.12174833e-03 1.35275759e-02 + 2.08116556e-03 3.12174833e-03 0. 2.08116556e-03 1.04058278e-03 + 3.12174833e-03 1.04058278e-03 4.16233111e-03 1.04058278e-03 0. 0. + 2.49739867e-02 1.04058278e-03 3.12174838e-02 9.36524477e-03 + 4.16233111e-03 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 1.04058273e-02 0. 1.04058278e-03 1.04058278e-03 4.16233111e-03 0. + 1.04058278e-03 1.04058278e-03 4.16233111e-03 1.04058278e-03 0. + 1.04058278e-03 1.97710730e-02 0. 2.08116546e-02 5.20291366e-03 + 2.28928216e-02 3.12174833e-03 0. 2.08116556e-03 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 3.12174833e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. + 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 7.28407968e-03 + 7.28407968e-03 1.04058278e-03 4.16233111e-03 1.04058278e-03 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 1.87304895e-02 + 3.12174833e-03 0. 2.08116556e-03 2.08116556e-03 0. 1.04058278e-03 + 1.04058278e-03 1.45681594e-02 2.08116556e-03 0. 0. 2.18522381e-02 + 0. 7.28407968e-03 2.08116556e-03 1.04058278e-03 8.32466222e-03 0. + 4.16233111e-03 3.12174833e-03 1.04058278e-03 0. 8.32466222e-03 0. + 0. 0. 1.04058278e-03 0. 0. 0. 3.12174833e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. + 6.24349667e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 0. 0. 7.28407968e-03 9.36524477e-03 4.47450578e-02 + 0. 2.18522381e-02 0. 1.04058278e-03 0. 1.45681594e-02 0. + 1.04058278e-03 0. 1.04058278e-03 2.08116556e-03 2.08116556e-03 0. + 4.16233111e-03 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. + 1.04058278e-03 2.08116556e-03 0. 0. 0. 2.08116556e-03 + 1.04058278e-03 3.12174833e-03 1.04058273e-02 5.09885550e-02 0. + 2.91363187e-02 1.04058278e-03 1.04058278e-03 1.04058278e-03 + 1.45681594e-02 1.04058278e-03 1.04058278e-03 0. 0. 0. + 4.16233111e-03 1.04058278e-03 1.24869933e-02 2.28928216e-02 + 4.37044762e-02 0. 1.76899079e-02 1.04058278e-03 2.08116556e-03 0. + 2.08116556e-03 1.35275759e-02 1.87304895e-02 1.04058278e-03 + 1.66493244e-02 2.18522381e-02 1.35275759e-02 1.87304895e-02 + 9.15712863e-02 5.30697219e-02 1.14464108e-02 0. 4.16233111e-03 + 8.32466222e-03 3.12174833e-03 2.08116556e-03 4.16233111e-03 + 3.12174833e-03 0. 0. 0. 3.12174833e-03 0. 1.04058278e-03 + 2.08116556e-03 8.32466222e-03 1.04058278e-03 0. 0. 6.24349667e-03 + 0. 0. 0. 4.16233111e-03 0. 0. 0. 1.97710730e-02 1.04058278e-03 + 1.24869933e-02 8.32466222e-03 7.28407968e-03 1.04058278e-03 0. 0. + 1.04058278e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 0. 1.14464108e-02 2.08116556e-03 0. 0. 5.20291366e-03 0. + 1.04058278e-03 0. 7.28407968e-03 0. 0. 0. 3.95421460e-02 0. + 1.35275759e-02 5.20291366e-03 2.28928216e-02 2.08116556e-03 + 1.04058278e-03 4.16233111e-03 4.16233111e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. + 0. 0. 0. 2.08116556e-03 0. 0. 0. 2.08116556e-03 0. 1.04058278e-03 + 0. 2.80957352e-02 2.08116556e-03 0. 2.08116556e-03 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 3.12174833e-03 + 0. 2.91363187e-02 1.04058278e-03 3.12174833e-03 0. 4.16233111e-03 + 0. 1.04058278e-03 1.04058278e-03 2.08116546e-02 0. 0. 0. + 1.87304895e-02 0. 9.36524477e-03 7.28407968e-03 4.16233111e-03 + 2.08116556e-03 0. 2.08116556e-03 2.08116556e-03 0. 0. + 1.04058273e-02 0. 0. 0. 0. 1.04058278e-03 2.08116556e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 3.12174833e-03 2.08116556e-03 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 2.08116556e-03 0. 1.04058278e-03 0. 1.04058278e-03 + 0. 0. 4.16233111e-03 1.04058278e-03 1.04058278e-03 7.28407968e-03 + 2.18522381e-02 3.32986489e-02 0. 3.85015644e-02 2.08116556e-03 0. + 0. 1.04058273e-02 0. 0. 0. 3.12174833e-03 0. 0. 0. 3.12174833e-03 + 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 3.12174833e-03 2.08116556e-03 + 0. 1.04058278e-03 0. 1.04058278e-03 0. 2.08116556e-03 + 1.24869933e-02 2.60145701e-02 1.04058278e-03 3.01769003e-02 0. 0. + 1.04058278e-03 7.28407968e-03 0. 0. 0. 3.12174833e-03 0. 0. 0. + 6.24349667e-03 2.28928216e-02 3.74609791e-02 2.08116556e-03 + 1.97710730e-02 3.12174833e-03 2.08116556e-03 2.08116556e-03 + 7.28407968e-03 1.97710730e-02 3.64203975e-02 0. 2.18522381e-02 + 1.66493244e-02 1.66493244e-02 7.28407968e-03 8.74089524e-02 + 4.47450578e-02 5.20291366e-03 1.04058278e-03 4.16233111e-03 + 1.45681594e-02 1.04058278e-03 4.16233111e-03 9.36524477e-03 + 1.04058278e-03 1.04058278e-03 0. 0. 4.16233111e-03 0. 0. + 1.66493244e-02 1.87304895e-02 4.16233111e-03 0. 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 4.16233111e-03 0. 0. 0. 2.39334032e-02 0. + 2.08116556e-03 1.04058278e-03 1.04058278e-03 0. 2.08116556e-03 0. + 5.20291366e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.35275759e-02 0. 0. 0. 5.20291366e-03 0. 0. 0. 2.08116556e-03 0. + 0. 0. 5.93132190e-02 0. 8.32466222e-03 7.28407968e-03 + 2.91363187e-02 0. 2.08116556e-03 2.08116556e-03 6.24349667e-03 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 3.12174833e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. + 2.08116556e-03 0. 0. 0. 3.12174833e-03 0. 0. 0. 1.76899079e-02 0. + 0. 1.04058278e-03 4.16233111e-03 0. 0. 1.04058278e-03 0. + 1.04058278e-03 0. 0. 2.08116556e-03 0. 0. 0. 3.64203975e-02 + 2.08116556e-03 1.04058278e-03 1.04058278e-03 4.16233111e-03 + 1.04058278e-03 2.08116556e-03 1.04058278e-03 2.70551518e-02 + 1.04058278e-03 1.04058278e-03 0. 6.13943823e-02 2.08116556e-03 + 9.36524477e-03 5.20291366e-03 1.04058278e-03 2.08116556e-03 0. + 2.08116556e-03 0. 1.04058278e-03 0. 2.08116546e-02 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 9.36524477e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 2.08116556e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 0. 1.04058278e-03 5.20291366e-03 3.12174833e-03 3.12174833e-03 + 1.56087419e-02 6.24349667e-03 2.39334032e-02 0. 4.68262248e-02 + 1.04058278e-03 2.08116556e-03 0. 1.76899079e-02 0. 0. 0. + 3.12174833e-03 1.04058278e-03 2.08116556e-03 0. 5.20291366e-03 + 2.08116556e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 0. 4.16233111e-03 1.04058278e-03 2.08116556e-03 0. + 5.20291366e-03 1.04058278e-03 2.28928216e-02 2.08116556e-03 + 1.45681594e-02 1.04058278e-03 1.04058278e-03 0. 6.24349667e-03 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 3.12174833e-03 + 3.12174833e-03 1.66493244e-02 0. 5.20291366e-03 2.08116556e-03 + 1.04058278e-03 0. 2.08116556e-03 1.56087419e-02 1.45681594e-02 + 4.16233111e-03 3.01769003e-02 1.97710730e-02 1.56087419e-02 + 5.20291366e-03 1.01977110e-01 1.76899079e-02 7.28407968e-03 0. + 4.16233111e-03 7.28407968e-03 3.12174833e-03 1.04058278e-03 + 2.28928216e-02 0. 1.04058278e-03 0. 0. 3.12174833e-03 0. + 1.76899079e-02 7.59625435e-02 1.14464108e-02 1.87304895e-02 0. + 1.04058278e-03 2.08116556e-03 2.08116556e-03 0. 1.04058278e-03 + 3.12174833e-03 1.04058278e-03 0. 0. 1.66493244e-02 1.04058278e-03 + 6.24349676e-02 8.42872038e-02 1.04058278e-03 2.08116556e-03 0. 0. + 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 4.16233111e-03 0. + 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 5.20291366e-03 + 1.04058278e-03 0. 1.04058278e-03 1.45681594e-02 1.04058278e-03 + 1.66493244e-02 7.28407968e-03 6.24349667e-03 1.04058278e-03 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 4.16233111e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 6.24349667e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. + 2.08116546e-02 1.04058278e-03 1.04058278e-03 0. 2.08116556e-03 + 1.04058278e-03 0. 1.04058278e-03 2.18522381e-02 0. 1.04058278e-03 + 1.04058278e-03 3.22580673e-02 0. 9.36524477e-03 1.04058278e-03 0. + 0. 0. 3.12174833e-03 0. 0. 0. 9.36524477e-03 0. 0. 0. 0. 0. 0. 0. + 7.28407968e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 4.16233111e-03 + 1.04058278e-03 1.24869933e-02 0. 3.12174833e-03 0. 0. 0. + 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 2.39334032e-02 3.12174838e-02 0. 3.12174833e-03 1.04058278e-03 0. + 0. 1.04058278e-03 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. + 1.14464108e-02 8.42872038e-02 9.36524495e-02 4.16233111e-03 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 1.04058278e-03 + 1.56087419e-02 1.24869933e-02 1.04058278e-03 4.16233111e-03 + 1.76899079e-02 8.32466222e-03 1.24869933e-02 6.34755492e-02 + 3.74609791e-02 1.14464108e-02 1.04058278e-03 8.32466222e-03 + 1.04058273e-02 4.16233111e-03 4.16233111e-03 1.56087419e-02 + 1.04058278e-03 2.08116556e-03 0. 0. 5.20291366e-03 3.12174833e-03 + 2.08116556e-03 3.32986489e-02 1.66493244e-02 4.16233111e-03 + 1.04058278e-03 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 5.20291366e-03 1.04058278e-03 0. 1.04058278e-03 1.66493244e-02 + 1.04058278e-03 3.43392305e-02 2.70551518e-02 1.04058278e-03 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 2.08116556e-03 4.16233111e-03 0. + 0. 0. 0. 1.04058278e-03 0. 0. 2.08116556e-03 0. 0. 0. + 4.16233111e-03 1.04058278e-03 6.24349667e-03 5.20291366e-03 + 1.24869933e-02 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 0. 3.12174833e-03 0. 2.08116556e-03 2.08116556e-03 + 6.24349667e-03 4.16233111e-03 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 4.05827276e-02 0. 0. 0. 4.16233111e-03 0. + 1.04058278e-03 1.04058278e-03 9.36524477e-03 0. 0. 0. + 6.24349667e-03 0. 3.12174833e-03 5.20291366e-03 3.12174833e-03 + 5.20291366e-03 0. 5.20291366e-03 0. 0. 0. 1.24869933e-02 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 9.36524477e-03 0. 0. 0. + 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 2.08116556e-03 2.08116556e-03 0. 9.36524477e-03 1.04058278e-03 0. + 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 4.16233111e-03 1.04058278e-03 0. 4.16233111e-03 + 3.12174833e-03 3.32986489e-02 0. 2.60145701e-02 0. 0. 0. + 2.08116546e-02 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. + 1.45681594e-02 3.12174833e-03 1.14464108e-02 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 0. 2.08116556e-03 + 0. 0. 1.04058273e-02 1.04058278e-03 2.08116546e-02 0. + 2.18522381e-02 1.04058278e-03 1.04058278e-03 2.08116556e-03 + 1.14464108e-02 1.04058278e-03 1.04058278e-03 0. 2.08116556e-03 0. + 0. 2.08116556e-03 1.04058273e-02 7.59625435e-02 3.74609791e-02 0. + 1.04058273e-02 1.04058278e-03 0. 1.04058278e-03 3.74609791e-02 + 2.60145701e-02 1.14464108e-02 1.04058278e-03 7.28407968e-03 + 7.28407968e-03 4.16233111e-03 9.36524477e-03 9.78147835e-02 + 5.51508889e-02 1.87304895e-02 2.08116556e-03 5.20291366e-03 + 1.35275759e-02 1.04058278e-03 3.12174833e-03 7.28407968e-03 0. + 1.04058278e-03 0. 0. 2.08116556e-03 0. 6.24349667e-03 + 4.16233111e-03 1.66493244e-02 0. 1.04058278e-03 0. 8.32466222e-03 + 0. 4.16233111e-03 1.04058278e-03 1.04058278e-03 0. 0. 0. + 4.57856432e-02 0. 7.18002096e-02 6.24349667e-03 2.08116556e-03 + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 8.32466222e-03 0. 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 2.08116556e-03 + 8.32466222e-03 0. 0. 0. 2.39334032e-02 0. 3.85015644e-02 + 8.32466222e-03 9.36524477e-03 7.28407968e-03 0. 1.04058278e-03 + 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 4.16233111e-03 3.12174833e-03 + 0. 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 2.08116556e-03 + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.14464108e-02 4.16233111e-03 + 1.04058278e-03 2.08116556e-03 0. 0. 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 0. 0. 1.04058278e-03 2.08116556e-03 1.04058278e-03 + 6.24349667e-03 1.04058278e-03 0. 5.20291366e-03 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 5.20291366e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 5.20291366e-03 3.12174833e-03 + 3.12174833e-03 8.32466222e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 1.04058278e-03 7.28407968e-03 5.20291366e-03 + 6.24349676e-02 0. 3.22580673e-02 0. 2.08116556e-03 0. + 3.12174833e-03 0. 2.08116556e-03 0. 1.04058278e-03 0. + 5.20291366e-03 0. 9.36524477e-03 1.04058278e-03 1.04058278e-03 0. + 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 3.12174833e-03 0. 0. + 5.20291366e-03 3.12174833e-03 3.12174833e-03 6.24349667e-03 + 5.20291366e-03 9.36524495e-02 0. 5.61914705e-02 1.04058278e-03 0. + 0. 7.28407968e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. 1.35275759e-02 + 1.66493244e-02 1.56087419e-02 0. 1.14464108e-02 0. 0. 0. + 5.20291366e-03 3.12174833e-03 1.14464108e-02 0. 7.28407968e-03 + 1.04058273e-02 1.04058273e-02 1.45681594e-02 7.18002096e-02 + 6.24349667e-03 9.36524477e-03 0. 4.16233111e-03 1.04058278e-03 + 4.16233111e-03 1.04058278e-03 1.76899079e-02 0. 0. 0. 0. 0. 0. + 9.36524477e-03 7.38813803e-02 5.20291366e-03 8.32466222e-03 0. + 3.12174833e-03 3.12174833e-03 1.04058278e-03 0. 1.24869933e-02 0. + 1.04058278e-03 0. 1.04058278e-03 2.28928216e-02 3.12174833e-03 + 2.49739867e-02 1.12382941e-01 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 4.16233111e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058273e-02 0. 0. 0. + 1.04058278e-03 0. 0. 2.08116556e-03 3.12174833e-03 0. 0. 0. + 2.18522381e-02 3.12174833e-03 2.08116556e-03 1.35275759e-02 0. + 1.04058278e-03 0. 3.12174833e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. + 0. 0. 0. 0. 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 1.04058278e-03 1.87304895e-02 0. 1.97710730e-02 0. 3.12174833e-03 + 0. 2.49739867e-02 0. 0. 0. 0. 0. 0. 0. 8.32466222e-03 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 3.12174833e-03 0. 0. 0. + 0. 0. 3.12174833e-03 0. 8.32466222e-03 3.01769003e-02 + 8.01248774e-02 0. 1.24869933e-02 0. 1.04058278e-03 0. + 9.36524477e-03 0. 0. 0. 0. 0. 0. 0. 4.16233111e-03 4.16233093e-02 + 1.77939653e-01 0. 9.36524477e-03 1.04058278e-03 0. 0. + 1.14464108e-02 2.08116556e-03 3.12174833e-03 0. 1.04058278e-03 + 6.24349667e-03 1.35275759e-02 5.20291366e-03 8.32466185e-02 + 1.76899079e-02 2.49739867e-02 0. 3.12174833e-03 4.16233111e-03 + 2.08116556e-03 0. 5.20291366e-03 0. 1.04058278e-03 0. 0. + 2.08116556e-03 0. 1.04058273e-02 3.74609791e-02 2.39334032e-02 + 1.87304895e-02 3.12174833e-03 0. 1.04058278e-03 0. 0. + 2.08116556e-03 4.16233111e-03 1.04058278e-03 0. 0. 1.76899079e-02 + 4.16233111e-03 3.12174838e-02 5.61914705e-02 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 3.12174833e-03 0. + 5.20291366e-03 9.36524477e-03 7.28407968e-03 1.04058278e-03 0. 0. + 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 8.32466222e-03 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 2.08116556e-03 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 2.39334032e-02 2.08116556e-03 0. 0. + 1.04058278e-03 0. 0. 0. 4.16233111e-03 1.04058278e-03 0. 0. + 1.04058273e-02 0. 1.56087419e-02 1.04058273e-02 2.08116556e-03 0. + 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 4.16233111e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 0. 0. 0. 0. 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 1.04058278e-03 2.18522381e-02 0. + 4.16233111e-03 0. 0. 0. 9.36524477e-03 0. 0. 0. 0. 0. 0. 0. + 1.35275759e-02 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 5.20291366e-03 1.97710730e-02 8.01248774e-02 + 0. 1.45681594e-02 1.04058278e-03 0. 1.04058278e-03 1.04058273e-02 + 0. 0. 0. 0. 0. 0. 4.16233111e-03 1.66493244e-02 4.78668064e-02 + 1.16545275e-01 0. 1.24869933e-02 1.04058278e-03 3.12174833e-03 0. + 1.87304895e-02 1.56087419e-02 1.45681594e-02 0. 5.20291366e-03 + 7.28407968e-03 1.24869933e-02 1.87304895e-02 1.10301778e-01 + 6.45161346e-02 1.04058273e-02 1.04058278e-03 6.24349667e-03 + 1.14464108e-02 0. 1.14464108e-02 2.08116546e-02 2.08116556e-03 0. + 1.04058278e-03 0. 6.24349667e-03 1.04058278e-03 2.28928216e-02 + 6.03538007e-02 1.35275759e-02 0. 1.04058278e-03 2.08116556e-03 + 5.20291366e-03 0. 2.08116556e-03 0. 4.16233111e-03 0. + 2.08116556e-03 1.04058278e-03 2.60145701e-02 2.08116556e-03 + 3.64203975e-02 2.91363187e-02 2.08116556e-03 0. 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.14464108e-02 2.08116556e-03 0. 2.08116556e-03 1.04058278e-03 + 1.04058278e-03 2.08116556e-03 1.04058278e-03 6.24349667e-03 + 1.04058278e-03 0. 0. 2.80957352e-02 0. 2.39334032e-02 + 7.28407968e-03 2.28928216e-02 8.32466222e-03 0. 1.04058278e-03 + 3.12174833e-03 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 1.14464108e-02 2.08116556e-03 + 1.04058278e-03 3.12174833e-03 1.04058278e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058273e-02 2.08116556e-03 + 0. 0. 0. 0. 0. 0. 7.28407968e-03 0. 0. 0. 8.32466222e-03 0. + 1.66493244e-02 2.08116556e-03 1.04058278e-03 3.12174833e-03 0. 0. + 0. 0. 1.04058278e-03 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. + 2.39334032e-02 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 2.08116556e-03 2.08116556e-03 4.16233111e-03 1.56087419e-02 0. 0. + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 + 1.04058278e-03 1.24869933e-02 6.24349667e-03 3.74609791e-02 0. + 1.14464108e-02 0. 0. 0. 8.32466222e-03 0. 5.20291366e-03 0. + 1.04058278e-03 0. 3.12174833e-03 1.04058278e-03 9.36524477e-03 + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 7.28407968e-03 4.16233111e-03 3.74609791e-02 0. + 3.22580673e-02 0. 0. 2.08116556e-03 1.04058273e-02 0. + 1.04058278e-03 0. 3.12174833e-03 0. 1.04058278e-03 1.04058278e-03 + 1.14464108e-02 6.24349667e-03 1.04058273e-02 0. 9.36524477e-03 0. + 0. 0. 2.08116556e-03 8.32466222e-03 1.56087419e-02 0. + 1.35275759e-02 8.32466222e-03 7.28407968e-03 8.32466222e-03 + 7.80437067e-02 8.74089524e-02 1.04058273e-02 2.08116556e-03 + 3.12174833e-03 1.76899079e-02 3.12174833e-03 8.32466222e-03 + 4.16233111e-03 2.08116556e-03 0. 0. 0. 8.32466222e-03 + 2.08116556e-03 8.32466222e-03 1.04058278e-03 2.28928216e-02 0. 0. + 0. 5.20291366e-03 0. 2.08116556e-03 0. 7.28407968e-03 0. 0. 0. + 3.43392305e-02 1.04058278e-03 9.36524477e-03 1.04058278e-03 + 4.16233111e-03 0. 1.04058278e-03 0. 7.28407968e-03 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058273e-02 + 0. 0. 1.04058278e-03 6.24349667e-03 1.04058278e-03 3.12174833e-03 + 1.04058278e-03 9.36524477e-03 1.04058278e-03 0. 1.04058278e-03 + 5.41103035e-02 1.04058278e-03 2.70551518e-02 1.14464108e-02 + 2.08116546e-02 3.12174833e-03 2.08116556e-03 1.04058278e-03 + 1.04058278e-03 0. 1.04058278e-03 0. 2.08116556e-03 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 2.08116556e-03 0. + 0. 1.04058278e-03 0. 0. 0. 0. 3.12174833e-03 0. 0. 0. + 1.04058278e-03 0. 0. 2.08116556e-03 1.14464108e-02 1.04058278e-03 + 1.04058278e-03 4.16233111e-03 1.04058278e-03 0. 0. 1.04058278e-03 + 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 2.18522381e-02 0. + 1.04058278e-03 4.16233111e-03 3.12174833e-03 0. 1.04058278e-03 + 2.08116556e-03 1.76899079e-02 0. 0. 1.04058278e-03 1.87304895e-02 + 3.12174833e-03 8.32466222e-03 9.36524477e-03 5.20291366e-03 + 4.16233111e-03 0. 7.28407968e-03 0. 1.04058278e-03 0. + 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 + 0. 0. 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. + 0. 2.08116556e-03 4.16233111e-03 0. 4.16233111e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 1.04058278e-03 6.24349667e-03 4.16233111e-03 + 4.16233111e-03 2.18522381e-02 1.04058273e-02 2.49739867e-02 + 1.04058278e-03 1.35275759e-02 0. 0. 1.04058278e-03 2.08116556e-03 + 2.08116556e-03 2.08116556e-03 0. 4.16233111e-03 0. 2.08116556e-03 + 0. 6.24349667e-03 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 3.12174833e-03 0. 2.08116556e-03 1.04058278e-03 2.08116556e-03 + 0. 5.20291366e-03 4.16233111e-03 1.87304895e-02 0. 2.70551518e-02 + 0. 0. 0. 1.14464108e-02 0. 1.04058278e-03 0. 2.08116556e-03 + 1.04058278e-03 0. 0. 1.35275759e-02 6.24349667e-03 1.04058273e-02 + 1.04058278e-03 1.24869933e-02 1.04058278e-03 0. 0. 6.24349667e-03 + 1.87304895e-02 1.04058273e-02 1.04058278e-03 1.24869933e-02 + 1.35275759e-02 1.24869933e-02 1.45681594e-02 9.05307010e-02 + 7.70031288e-02 9.36524477e-03 1.04058278e-03 2.08116556e-03 + 3.32986489e-02 6.24349667e-03 4.16233111e-03 7.28407968e-03 + 5.20291366e-03 1.04058278e-03 1.04058278e-03 1.04058278e-03 + 3.12174833e-03 2.08116556e-03 1.04058278e-03 7.28407968e-03 + 1.45681594e-02 3.12174833e-03 0. 0. 5.20291366e-03 0. + 1.04058278e-03 0. 1.45681594e-02 0. 0. 0. 2.39334032e-02 + 3.12174833e-03 4.16233111e-03 7.28407968e-03 4.16233111e-03 + 1.04058278e-03 0. 0. 2.08116556e-03 0. 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 0. 2.08116556e-03 0. 0. 2.08116556e-03 + 1.04058273e-02 0. 0. 0. 4.16233111e-03 0. 2.08116556e-03 + 2.08116556e-03 1.56087419e-02 0. 0. 2.08116556e-03 4.89073917e-02 + 1.04058278e-03 2.39334032e-02 8.32466222e-03 1.97710730e-02 + 1.04058278e-03 0. 2.08116556e-03 4.16233111e-03 0. 2.08116556e-03 + 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 + 0. 0. 2.08116556e-03 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 0. + 0. 0. 0. 0. 1.04058278e-03 1.35275759e-02 1.04058278e-03 0. + 2.08116556e-03 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 3.12174833e-03 0. 1.04058278e-03 0. 3.95421460e-02 0. + 1.04058278e-03 2.08116556e-03 0. 0. 1.04058278e-03 0. + 3.64203975e-02 2.08116556e-03 4.16233111e-03 3.12174833e-03 + 2.08116546e-02 1.04058278e-03 1.45681594e-02 1.56087419e-02 + 3.12174833e-03 3.12174833e-03 0. 3.12174833e-03 0. 2.08116556e-03 + 0. 2.08116556e-03 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 0. 4.16233111e-03 1.04058278e-03 1.04058278e-03 0. + 0. 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 0. 0. 1.04058278e-03 + 4.16233111e-03 0. 6.24349667e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 3.12174833e-03 2.08116556e-03 1.04058278e-03 0. + 1.04058278e-03 5.20291366e-03 3.12174833e-03 2.08116556e-03 + 1.35275759e-02 3.12174833e-03 1.97710730e-02 0. 1.56087419e-02 0. + 0. 0. 6.24349667e-03 1.04058278e-03 1.04058278e-03 0. + 1.04058278e-03 1.04058278e-03 0. 0. 8.32466222e-03 2.08116556e-03 + 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 2.08116556e-03 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 2.08116556e-03 + 4.16233111e-03 7.28407968e-03 0. 2.60145701e-02 0. 0. 0. + 4.16233111e-03 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. + 1.04058278e-03 6.24349667e-03 1.14464108e-02 7.28407968e-03 0. + 7.28407968e-03 1.04058278e-03 0. 0. 3.12174833e-03 1.76899079e-02 + 1.35275759e-02 0. 3.01769003e-02 1.76899079e-02 9.36524477e-03 + 1.87304895e-02 9.36524495e-02 5.61914705e-02 9.36524477e-03 + 3.12174833e-03 2.08116556e-03 1.76899079e-02 2.08116556e-03 + 2.08116556e-03 5.20291366e-03 2.08116556e-03 0. 0. 0. + 2.08116556e-03 1.04058278e-03 2.08116556e-03 1.35275759e-02 + 9.36524477e-03 1.04058278e-03 0. 1.04058278e-03 5.20291366e-03 + 1.04058278e-03 1.04058278e-03 0. 6.24349667e-03 1.04058278e-03 0. + 0. 2.80957352e-02 2.08116556e-03 1.87304895e-02 8.32466222e-03 + 4.16233111e-03 0. 0. 1.04058278e-03 2.08116556e-03 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 7.28407968e-03 + 3.12174833e-03 0. 0. 1.04058273e-02 0. 2.08116556e-03 0. + 7.28407968e-03 0. 0. 0. 5.61914705e-02 2.08116556e-03 + 2.39334032e-02 6.24349667e-03 2.80957352e-02 3.12174833e-03 + 4.16233111e-03 1.04058278e-03 1.04058278e-03 0. 0. 2.08116556e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 2.08116556e-03 0. + 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 2.08116556e-03 0. 0. 0. + 0. 0. 0. 1.04058278e-03 3.12174833e-03 2.08116556e-03 + 2.08116556e-03 1.04058278e-03 2.08116556e-03 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.28928216e-02 0. 0. + 1.04058278e-03 2.08116556e-03 0. 2.08116556e-03 2.08116556e-03 + 1.04058273e-02 0. 0. 0. 3.01769003e-02 1.04058278e-03 + 9.36524477e-03 3.12174833e-03 1.04058278e-03 4.16233111e-03 0. + 2.08116556e-03 0. 0. 0. 7.28407968e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 7.28407968e-03 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 2.08116556e-03 + 1.04058278e-03 1.04058278e-03 8.32466222e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 + 1.04058278e-03 2.08116556e-03 1.45681594e-02 2.08116556e-03 + 3.32986489e-02 0. 8.01248774e-02 0. 1.04058278e-03 0. + 2.28928216e-02 0. 1.04058278e-03 0. 5.20291366e-03 1.04058278e-03 + 1.04058278e-03 0. 4.16233111e-03 3.12174833e-03 5.20291366e-03 0. + 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 3.12174833e-03 + 1.04058278e-03 4.16233111e-03 0. 0. 2.08116556e-03 6.24349667e-03 + 0. 6.24349667e-03 2.08116556e-03 6.24349667e-03 0. 2.08116546e-02 + 1.04058278e-03 1.04058278e-03 0. 8.32466222e-03 1.04058278e-03 + 1.04058278e-03 0. 3.12174833e-03 1.04058278e-03 1.04058278e-03 0. + 5.20291366e-03 1.56087419e-02 1.14464108e-02 1.04058278e-03 + 1.45681594e-02 2.08116556e-03 0. 0. 1.04058273e-02 1.24869933e-02 + 1.04058273e-02 0. 1.87304895e-02 1.56087419e-02 7.28407968e-03 + 7.28407968e-03 9.26118642e-02 6.13943823e-02 2.18522381e-02 + 2.08116556e-03 4.16233111e-03 1.56087419e-02 1.04058278e-03 + 1.04058278e-03 5.20291366e-03 1.04058278e-03 2.08116556e-03 0. 0. + 7.28407968e-03 1.04058278e-03 5.20291366e-03 1.14464108e-02 + 2.70551518e-02 3.12174833e-03 1.04058278e-03 2.08116556e-03 + 5.20291366e-03 0. 0. 1.04058278e-03 7.28407968e-03 1.04058278e-03 + 0. 0. 2.28928216e-02 1.04058278e-03 6.13943823e-02 1.04058273e-02 + 1.04058278e-03 2.08116556e-03 1.04058278e-03 2.08116556e-03 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 5.20291366e-03 1.04058278e-03 0. 0. 3.12174833e-03 0. + 2.08116556e-03 2.08116556e-03 3.12174833e-03 1.04058278e-03 0. 0. + 4.26638946e-02 0. 1.97710730e-02 9.36524477e-03 8.32466222e-03 + 3.12174833e-03 0. 1.04058278e-03 1.04058278e-03 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 2.08116556e-03 0. 5.20291366e-03 + 2.08116556e-03 2.08116556e-03 1.04058278e-03 0. 0. 2.08116556e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 1.24869933e-02 + 4.16233111e-03 1.04058278e-03 5.20291366e-03 2.08116556e-03 0. 0. + 0. 6.24349667e-03 0. 0. 0. 1.14464108e-02 0. 8.32466222e-03 + 4.16233111e-03 3.12174833e-03 3.12174833e-03 0. 4.16233111e-03 0. + 2.08116556e-03 0. 4.16233111e-03 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 9.36524477e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 2.08116556e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 2.08116556e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 3.12174833e-03 1.04058273e-02 1.24869933e-02 + 3.22580673e-02 0. 2.70551518e-02 0. 0. 0. 1.24869933e-02 + 1.04058278e-03 3.12174833e-03 0. 2.08116556e-03 0. 1.04058278e-03 + 1.04058278e-03 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 2.08116556e-03 4.16233111e-03 + 2.08116556e-03 4.16233111e-03 6.24349667e-03 5.51508889e-02 0. + 3.85015644e-02 0. 0. 0. 1.35275759e-02 1.04058278e-03 + 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 + 1.56087419e-02 1.87304895e-02 3.53798158e-02 2.08116556e-03 + 5.20291366e-03 1.04058278e-03 0. 1.04058278e-03 9.36524477e-03 + 1.35275759e-02 1.04058273e-02 0. 1.45681594e-02 9.36524477e-03 + 5.20291366e-03 1.87304895e-02 8.01248774e-02 2.08116546e-02 + 1.56087419e-02 0. 2.08116556e-03 1.56087419e-02 4.16233111e-03 + 6.24349667e-03 2.60145701e-02 0. 0. 0. 0. 5.20291366e-03 0. + 3.12174833e-03 5.20291366e-03 2.08116546e-02 1.14464108e-02 + 1.04058278e-03 3.12174833e-03 1.04058278e-03 0. 3.12174833e-03 + 6.24349667e-03 0. 1.04058278e-03 0. 0. 3.43392305e-02 + 2.08116556e-03 1.66493244e-02 4.78668064e-02 0. 1.04058278e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 0. 2.08116556e-03 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 1.14464108e-02 1.04058278e-03 1.56087419e-02 1.56087419e-02 + 6.24349667e-03 7.28407968e-03 0. 0. 1.04058278e-03 0. + 1.04058278e-03 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. + 2.08116556e-03 1.04058278e-03 2.08116556e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.14464108e-02 + 4.16233111e-03 0. 0. 1.04058278e-03 0. 1.04058278e-03 + 2.08116556e-03 4.16233111e-03 0. 0. 0. 1.45681594e-02 0. + 9.36524477e-03 1.56087419e-02 0. 1.04058278e-03 0. 1.04058278e-03 + 0. 0. 0. 4.16233111e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058273e-02 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 + 1.24869933e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 6.24349667e-03 5.20291366e-03 4.26638946e-02 0. 1.04058273e-02 0. + 1.04058278e-03 0. 1.14464108e-02 0. 2.08116556e-03 0. + 1.04058278e-03 0. 1.04058278e-03 0. 1.35275759e-02 0. 0. 0. 0. 0. + 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 + 3.01769003e-02 5.20291366e-03 1.31113425e-01 0. 2.91363187e-02 + 1.04058278e-03 3.12174833e-03 0. 1.14464108e-02 0. 1.04058278e-03 + 0. 0. 0. 0. 0. 7.28407968e-03 6.24349667e-03 2.39334032e-02 0. + 9.36524477e-03 1.04058278e-03 1.04058278e-03 0. 7.28407968e-03 + 1.04058278e-03 8.32466222e-03 0. 9.36524477e-03 1.14464108e-02 + 1.66493244e-02 6.24349667e-03 1.50884509e-01 4.16233111e-03 + 1.56087419e-02 0. 1.04058278e-03 5.20291366e-03 0. 4.16233111e-03 + 1.45681594e-02 0. 0. 0. 0. 3.12174833e-03 0. 3.12174833e-03 + 6.03538007e-02 1.04058273e-02 2.60145701e-02 1.04058278e-03 0. + 2.08116556e-03 0. 0. 1.24869933e-02 0. 3.12174833e-03 0. + 1.04058278e-03 1.45681594e-02 0. 3.01769003e-02 2.01873064e-01 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 6.24349667e-03 0. 6.24349667e-03 + 1.45681594e-02 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 9.36524477e-03 2.08116556e-03 0. 0. + 2.08116556e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. + 1.24869933e-02 2.08116556e-03 4.16233111e-03 6.24349667e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 5.20291366e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 3.12174833e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 1.24869933e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 8.32466222e-03 0. 1.04058278e-03 0. 0. 0. 9.36524477e-03 0. + 0. 0. 0. 0. 0. 0. 6.24349667e-03 0. 2.08116556e-03 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 1.04058273e-02 7.28407968e-03 4.26638946e-02 0. + 2.08116556e-03 0. 0. 0. 1.14464108e-02 0. 0. 0. 0. 0. 0. + 1.04058278e-03 5.20291366e-03 8.74089524e-02 1.81061402e-01 0. + 4.16233111e-03 0. 1.04058278e-03 0. 1.87304895e-02 3.12174833e-03 + 5.20291366e-03 0. 2.08116556e-03 2.08116556e-03 4.16233111e-03 + 1.04058273e-02 5.72320521e-02 2.80957352e-02 1.76899079e-02 + 1.04058278e-03 4.16233111e-03 3.12174833e-03 1.04058278e-03 + 4.16233111e-03 2.08116546e-02 1.04058278e-03 0. 0. 0. 0. 0. + 7.28407968e-03 2.60145701e-02 1.76899079e-02 1.45681594e-02 + 1.04058278e-03 2.08116556e-03 0. 0. 0. 2.08116556e-03 0. + 2.08116556e-03 0. 0. 1.04058273e-02 1.04058278e-03 2.49739867e-02 + 3.32986489e-02 0. 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 0. + 0. 0. 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. + 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 7.28407968e-03 + 1.04058278e-03 3.12174833e-03 4.16233111e-03 1.45681594e-02 + 1.04058278e-03 0. 1.04058278e-03 7.28407968e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 5.20291366e-03 2.08116556e-03 1.04058278e-03 1.04058278e-03 0. 0. + 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 1.97710730e-02 + 2.08116556e-03 0. 0. 2.08116556e-03 0. 1.04058278e-03 0. + 8.32466222e-03 0. 0. 1.04058278e-03 1.45681594e-02 0. + 2.08116556e-03 3.12174833e-03 0. 2.08116556e-03 0. 4.16233111e-03 + 0. 1.04058278e-03 0. 5.20291366e-03 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 1.14464108e-02 1.04058278e-03 2.08116556e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 + 9.36524477e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 4.16233111e-03 2.08116556e-03 3.74609791e-02 0. + 8.32466222e-03 2.08116556e-03 0. 0. 1.45681594e-02 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 1.35275759e-02 + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 0. 0. 0. 0. 1.04058278e-03 1.14464108e-02 1.56087419e-02 + 7.49219581e-02 0. 2.60145701e-02 1.04058278e-03 3.12174833e-03 0. + 1.45681594e-02 0. 0. 0. 0. 0. 1.04058278e-03 3.12174833e-03 + 3.01769003e-02 5.09885550e-02 1.05098858e-01 1.04058278e-03 + 1.87304895e-02 2.08116556e-03 1.04058278e-03 0. 1.14464108e-02 + 6.24349667e-03 1.87304895e-02 0. 1.35275759e-02 6.24349667e-03 + 1.04058273e-02 1.66493244e-02 8.22060406e-02 7.07596317e-02 + 2.39334032e-02 6.24349667e-03 1.04058273e-02 1.24869933e-02 + 2.08116556e-03 9.36524477e-03 1.14464108e-02 3.12174833e-03 0. 0. + 1.04058278e-03 7.28407968e-03 3.12174833e-03 1.35275759e-02 + 3.01769003e-02 3.32986489e-02 5.20291366e-03 0. 1.04058278e-03 + 3.12174833e-03 0. 5.20291366e-03 1.04058278e-03 6.24349667e-03 + 1.04058278e-03 0. 0. 3.95421460e-02 0. 5.20291403e-02 + 2.49739867e-02 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. + 2.08116556e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 7.28407968e-03 1.04058278e-03 0. 2.08116556e-03 3.12174833e-03 0. + 2.08116556e-03 0. 4.16233111e-03 1.04058278e-03 0. 1.04058278e-03 + 1.87304895e-02 1.04058278e-03 3.32986489e-02 1.24869933e-02 + 6.24349667e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 2.08116556e-03 2.08116556e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 3.12174833e-03 0. 0. 0. + 1.45681594e-02 1.04058278e-03 0. 2.08116556e-03 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 2.08116556e-03 1.35275759e-02 0. 0. 2.08116556e-03 0. 0. + 1.04058278e-03 1.04058278e-03 8.32466222e-03 0. 1.04058278e-03 + 1.04058278e-03 1.14464108e-02 0. 1.35275759e-02 1.04058278e-03 + 1.04058278e-03 8.32466222e-03 0. 1.04058278e-03 0. 0. 0. + 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 1.35275759e-02 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 0. 1.04058278e-03 2.08116556e-03 3.12174833e-03 + 1.14464108e-02 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 0. + 2.08116556e-03 7.28407968e-03 2.08116556e-03 2.80957352e-02 0. + 1.66493244e-02 1.04058278e-03 2.08116556e-03 1.04058278e-03 + 4.16233111e-03 0. 2.08116556e-03 0. 0. 2.08116556e-03 0. 0. + 1.14464108e-02 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 1.04058278e-03 + 3.12174833e-03 9.36524477e-03 5.20291366e-03 2.39334032e-02 + 1.04058278e-03 2.80957352e-02 0. 1.04058278e-03 0. 2.08116556e-03 + 1.04058278e-03 2.08116556e-03 1.04058278e-03 0. 2.08116556e-03 + 4.16233111e-03 3.12174833e-03 1.87304895e-02 2.70551518e-02 + 3.12174833e-03 1.04058278e-03 4.16233111e-03 1.04058278e-03 0. 0. + 6.24349667e-03 6.24349667e-03 1.04058273e-02 0. 8.32466222e-03 + 5.20291366e-03 9.36524477e-03 2.08116546e-02 8.01248774e-02 + 8.42872038e-02 3.22580673e-02 3.12174833e-03 7.28407968e-03 + 1.45681594e-02 2.08116556e-03 6.24349667e-03 1.04058273e-02 + 2.08116556e-03 1.04058278e-03 1.04058278e-03 0. 8.32466222e-03 + 3.12174833e-03 1.04058273e-02 2.18522381e-02 2.80957352e-02 + 4.16233111e-03 3.12174833e-03 1.04058278e-03 2.08116556e-03 0. + 3.12174833e-03 0. 1.45681594e-02 3.12174833e-03 0. 0. + 2.18522381e-02 1.04058278e-03 2.49739867e-02 8.32466222e-03 + 1.04058278e-03 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 0. + 0. 0. 2.08116556e-03 0. 0. 0. 2.08116556e-03 1.04058278e-03 0. + 1.04058278e-03 1.04058273e-02 0. 0. 1.04058278e-03 1.04058278e-03 + 0. 4.16233111e-03 0. 4.16233111e-03 1.04058278e-03 0. + 1.04058278e-03 2.49739867e-02 2.08116556e-03 2.08116546e-02 + 1.35275759e-02 1.04058273e-02 3.12174833e-03 0. 2.08116556e-03 + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. + 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. + 1.04058278e-03 0. 6.24349667e-03 4.16233111e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 1.04058278e-03 2.08116556e-03 0. 2.08116556e-03 + 0. 0. 3.12174833e-03 1.04058278e-03 1.04058278e-03 2.08116556e-03 + 1.04058273e-02 0. 3.12174833e-03 1.04058278e-03 0. 0. + 2.08116556e-03 0. 5.20291366e-03 0. 1.04058278e-03 1.04058278e-03 + 7.28407968e-03 1.04058278e-03 1.45681594e-02 2.08116556e-03 + 1.04058278e-03 7.28407968e-03 0. 0. 1.04058278e-03 1.04058278e-03 + 0. 2.08116556e-03 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. + 1.04058278e-03 7.28407968e-03 3.12174833e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 3.12174833e-03 + 1.04058278e-03 3.12174833e-03 5.20291366e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 2.08116556e-03 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 3.12174833e-03 0. + 7.28407968e-03 1.35275759e-02 5.20291366e-03 1.66493244e-02 0. + 4.16233111e-03 0. 1.04058278e-03 0. 2.08116556e-03 0. + 1.04058278e-03 0. 0. 0. 2.08116556e-03 1.04058278e-03 + 4.16233111e-03 2.08116556e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. + 2.08116556e-03 1.04058278e-03 0. 2.08116556e-03 1.04058278e-03 0. + 3.12174833e-03 5.20291366e-03 8.32466222e-03 4.37044762e-02 0. + 1.66493244e-02 2.08116556e-03 1.04058278e-03 2.08116556e-03 + 7.28407968e-03 1.04058278e-03 1.04058278e-03 0. 6.24349667e-03 + 1.04058278e-03 0. 3.12174833e-03 2.91363187e-02 2.08116546e-02 + 1.14464108e-02 0. 7.28407968e-03 0. 0. 1.04058278e-03 + 4.16233111e-03 1.24869933e-02 3.12174833e-03 2.08116556e-03 + 7.28407968e-03 1.14464108e-02 7.28407968e-03 3.74609791e-02 + 1.04058281e-01 6.65972978e-02 1.45681594e-02 9.36524477e-03 + 6.24349667e-03 1.35275759e-02 2.08116556e-03 6.24349667e-03 + 5.20291366e-03 1.04058278e-03 0. 0. 0. 6.24349667e-03 + 1.04058278e-03 4.16233111e-03 6.24349667e-03 2.08116546e-02 + 1.04058278e-03 1.04058278e-03 0. 4.16233111e-03 0. 3.12174833e-03 + 1.04058278e-03 4.16233111e-03 0. 0. 0. 2.39334032e-02 + 1.04058278e-03 3.22580673e-02 1.04058273e-02 4.16233111e-03 + 3.12174833e-03 1.04058278e-03 1.04058278e-03 3.12174833e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 4.16233111e-03 + 1.04058278e-03 0. 0. 2.08116556e-03 0. 4.16233111e-03 0. + 7.28407968e-03 0. 0. 1.04058278e-03 3.12174838e-02 1.04058278e-03 + 2.49739867e-02 6.24349667e-03 1.04058273e-02 2.08116556e-03 + 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 6.24349667e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 3.12174833e-03 1.04058278e-03 0. + 0. 1.04058278e-03 0. 2.08116556e-03 0. 1.04058273e-02 + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 1.56087419e-02 + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 2.80957352e-02 0. 1.04058278e-03 0. 1.76899079e-02 0. + 1.04058273e-02 3.12174833e-03 2.08116556e-03 5.20291366e-03 0. + 3.12174833e-03 0. 0. 2.08116556e-03 5.20291366e-03 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 3.12174833e-03 1.04058278e-03 + 3.12174833e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 4.16233111e-03 8.32466222e-03 0. 0. + 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. + 2.08116556e-03 2.08116556e-03 2.08116556e-03 1.35275759e-02 + 8.32466222e-03 4.68262248e-02 0. 2.60145701e-02 1.04058278e-03 + 3.12174833e-03 0. 5.20291366e-03 0. 1.04058278e-03 0. + 3.12174833e-03 0. 3.12174833e-03 2.08116556e-03 2.08116556e-03 0. + 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. + 0. 0. 2.08116556e-03 0. 7.28407968e-03 8.32466222e-03 + 4.47450578e-02 0. 3.12174838e-02 3.12174833e-03 0. 0. + 1.14464108e-02 0. 2.08116556e-03 0. 0. 1.04058278e-03 0. + 2.08116556e-03 1.56087419e-02 3.43392305e-02 3.01769003e-02 + 1.04058278e-03 1.35275759e-02 1.04058278e-03 2.08116556e-03 0. + 5.20291366e-03 1.04058273e-02 1.14464108e-02 0. 9.36524477e-03 + 1.45681594e-02 7.28407968e-03 1.24869933e-02 7.59625435e-02 + 4.78668064e-02 1.97710730e-02 2.08116556e-03 2.08116556e-03 + 7.28407968e-03 2.08116556e-03 1.04058278e-03 1.04058273e-02 0. + 2.08116556e-03 0. 1.04058278e-03 5.20291366e-03 2.08116556e-03 + 1.35275759e-02 1.31113425e-01 1.24869933e-02 1.04058278e-03 0. + 1.04058278e-03 5.20291366e-03 0. 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 1.04058278e-03 1.04058278e-03 0. 1.35275759e-02 0. + 3.12174838e-02 2.91363187e-02 4.16233111e-03 0. 1.04058278e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 2.08116556e-03 + 1.04058273e-02 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 3.01769003e-02 0. + 1.24869933e-02 4.16233111e-03 1.87304895e-02 1.04058278e-03 0. + 1.04058278e-03 4.16233111e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. + 2.08116556e-03 0. 0. 1.04058278e-03 5.20291366e-03 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 1.04058278e-03 7.28407968e-03 1.04058278e-03 + 0. 2.08116556e-03 1.04058278e-03 0. 1.04058278e-03 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 2.18522381e-02 0. + 0. 0. 2.08116556e-03 0. 0. 0. 9.36524477e-03 1.04058278e-03 0. + 1.04058278e-03 8.32466222e-03 0. 3.12174833e-03 4.16233111e-03 + 1.04058278e-03 6.24349667e-03 0. 6.24349667e-03 1.04058278e-03 + 2.08116556e-03 1.04058278e-03 6.24349667e-03 0. 1.04058278e-03 0. + 0. 0. 0. 0. 8.32466222e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 + 0. 9.36524477e-03 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 3.12174833e-03 0. + 6.24349667e-03 3.12174833e-03 1.87304895e-02 0. 1.97710730e-02 0. + 0. 0. 1.35275759e-02 0. 1.04058278e-03 0. 0. 0. 0. 0. + 6.24349667e-03 3.12174833e-03 1.04058278e-03 0. 2.08116556e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 1.14464108e-02 2.70551518e-02 0. 1.56087419e-02 2.08116556e-03 0. + 0. 9.36524477e-03 0. 1.04058278e-03 0. 1.04058278e-03 + 2.08116556e-03 3.12174833e-03 0. 1.35275759e-02 6.55567124e-02 + 3.32986489e-02 1.04058278e-03 1.04058273e-02 1.04058278e-03 + 1.04058278e-03 0. 5.20291366e-03 1.35275759e-02 1.45681594e-02 + 2.08116556e-03 1.24869933e-02 1.24869933e-02 8.32466222e-03 + 1.24869933e-02 6.24349676e-02 5.09885550e-02 3.53798158e-02 + 1.04058278e-03 6.24349667e-03 5.20291366e-03 0. 5.20291366e-03 + 1.14464108e-02 1.04058278e-03 0. 0. 0. 6.24349667e-03 0. + 8.32466222e-03 8.32466222e-03 2.18522381e-02 6.24349667e-03 0. + 2.08116556e-03 1.04058278e-03 0. 5.20291366e-03 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 0. 0. 2.60145701e-02 1.04058278e-03 + 5.61914705e-02 1.97710730e-02 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.35275759e-02 2.08116556e-03 + 0. 0. 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 + 3.12174833e-03 0. 0. 1.04058278e-03 1.45681594e-02 0. + 1.66493244e-02 6.24349667e-03 1.45681594e-02 5.20291366e-03 0. + 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 2.08116556e-03 0. + 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 2.08116556e-03 0. 1.04058278e-03 2.08116556e-03 + 5.20291366e-03 2.08116556e-03 1.04058278e-03 0. 1.04058278e-03 0. + 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 6.24349667e-03 1.04058278e-03 0. 3.12174833e-03 0. 0. + 1.04058278e-03 0. 3.12174833e-03 0. 0. 0. 7.28407968e-03 0. + 7.28407968e-03 3.12174833e-03 2.08116556e-03 7.28407968e-03 0. + 5.20291366e-03 0. 1.04058278e-03 1.04058278e-03 3.12174833e-03 0. + 0. 0. 0. 0. 0. 0. 1.04058273e-02 0. 0. 0. 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 0. 2.08116556e-03 6.24349667e-03 0. + 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 8.32466222e-03 + 3.12174833e-03 2.70551518e-02 0. 1.97710730e-02 4.16233111e-03 + 3.12174833e-03 0. 8.32466222e-03 1.04058278e-03 2.08116556e-03 0. + 1.04058278e-03 1.04058278e-03 0. 0. 7.28407968e-03 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 2.08116556e-03 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 1.04058278e-03 1.14464108e-02 8.32466222e-03 + 1.47762761e-01 0. 2.18522381e-02 3.12174833e-03 0. 2.08116556e-03 + 1.35275759e-02 2.08116556e-03 3.12174833e-03 1.04058278e-03 + 4.16233111e-03 0. 2.08116556e-03 2.08116556e-03 2.39334032e-02 + 1.04058273e-02 1.97710730e-02 0. 1.24869933e-02 2.08116556e-03 0. + 0. 4.16233111e-03 1.04058278e-03 8.32466222e-03 1.04058278e-03 + 7.28407968e-03 7.28407968e-03 7.28407968e-03 1.66493244e-02 + 8.53277892e-02 1.24869933e-02 9.36524477e-03 0. 1.04058278e-03 + 9.36524477e-03 0. 2.08116556e-03 6.24349676e-02 0. 0. 0. 0. + 3.12174833e-03 0. 0. 2.08116546e-02 7.28407968e-03 2.08116556e-03 + 1.04058278e-03 0. 0. 0. 0. 3.12174833e-03 1.04058278e-03 0. 0. 0. + 3.01769003e-02 2.08116556e-03 1.87304895e-02 5.93132190e-02 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. + 4.16233111e-03 0. 0. 0. 1.56087419e-02 0. 5.20291366e-03 + 1.45681594e-02 3.12174833e-03 0. 0. 1.04058278e-03 3.12174833e-03 + 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 3.12174833e-03 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 0. 0. 2.18522381e-02 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 2.08116556e-03 + 1.04058278e-03 7.28407949e-02 1.04058278e-03 0. 0. 7.18002096e-02 + 1.04058278e-03 1.87304895e-02 1.66493244e-02 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. 6.65972978e-02 0. 0. 0. + 0. 0. 0. 0. 2.39334032e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.45681594e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 5.20291366e-03 + 2.08116556e-03 1.24869933e-02 0. 4.16233111e-03 1.04058278e-03 + 5.20291366e-03 0. 4.78668064e-02 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.45681594e-02 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. + 3.12174833e-03 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. + 3.85015644e-02 1.04058278e-03 3.01769003e-02 0. 2.08116556e-03 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 4.16233111e-03 + 3.12174833e-03 1.56087419e-02 0. 8.32466222e-03 0. 1.04058278e-03 + 0. 6.24349667e-03 3.12174833e-03 9.36524477e-03 0. 2.08116556e-03 + 7.28407968e-03 1.66493244e-02 3.12174833e-03 1.17585853e-01 + 7.28407968e-03 1.24869933e-02 0. 5.20291366e-03 6.24349667e-03 0. + 2.08116556e-03 8.32466222e-03 1.04058278e-03 0. 0. 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 1.87304895e-02 7.07596317e-02 + 9.36524477e-03 1.66493244e-02 0. 1.04058278e-03 0. 1.04058278e-03 + 0. 2.08116556e-03 7.28407968e-03 2.08116556e-03 0. 0. + 3.32986489e-02 3.12174833e-03 1.03017695e-01 1.25910521e-01 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 8.32466222e-03 + 1.04058278e-03 0. 0. 1.66493244e-02 0. 2.08116546e-02 + 8.32466222e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 7.28407968e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 2.08116556e-03 0. + 0. 1.04058278e-03 6.24349667e-03 0. 2.28928216e-02 4.16233111e-03 + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 3.12174833e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 0. + 9.36524477e-03 0. 1.04058278e-03 0. 0. 0. 3.12174833e-03 0. 0. 0. + 0. 1.04058278e-03 0. 0. 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 4.16233111e-03 7.28407968e-03 2.91363187e-02 0. + 0. 0. 0. 1.04058278e-03 3.12174833e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058273e-02 1.09261192e-01 1.61290333e-01 0. + 2.08116556e-03 0. 0. 0. 2.08116556e-03 0. 1.04058278e-03 0. + 1.04058278e-03 1.97710730e-02 3.12174833e-03 1.76899079e-02 + 3.85015644e-02 5.30697219e-02 1.56087419e-02 3.12174833e-03 + 5.20291366e-03 1.14464108e-02 0. 5.20291366e-03 3.12174833e-03 + 2.08116556e-03 0. 1.04058278e-03 3.12174833e-03 4.16233111e-03 0. + 1.24869933e-02 2.08116546e-02 2.18522381e-02 1.04058278e-03 0. 0. + 4.16233111e-03 0. 1.04058278e-03 1.04058278e-03 3.12174833e-03 + 1.04058278e-03 0. 2.08116556e-03 1.76899079e-02 1.04058278e-03 + 2.49739867e-02 3.12174838e-02 2.08116556e-03 2.08116556e-03 0. + 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. 1.04058278e-03 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 1.14464108e-02 2.08116556e-03 0. + 0. 0. 0. 2.08116556e-03 1.04058278e-03 5.20291366e-03 0. 0. + 1.04058278e-03 2.08116546e-02 0. 2.70551518e-02 5.20291366e-03 + 2.08116546e-02 2.08116556e-03 1.04058278e-03 3.12174833e-03 + 2.08116556e-03 0. 1.04058278e-03 3.12174833e-03 1.04058278e-03 0. + 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 2.08116556e-03 + 7.28407968e-03 2.08116556e-03 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.56087419e-02 0. + 1.04058278e-03 0. 2.08116556e-03 0. 0. 1.04058278e-03 + 7.28407968e-03 0. 1.04058278e-03 0. 8.32466222e-03 0. + 7.28407968e-03 2.08116556e-03 1.04058278e-03 8.32466222e-03 + 1.04058278e-03 7.28407968e-03 0. 0. 0. 7.28407968e-03 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 6.24349667e-03 1.04058278e-03 + 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 1.04058278e-03 0. 2.08116556e-03 7.28407968e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 3.12174833e-03 + 1.04058278e-03 4.16233111e-03 1.04058273e-02 1.04058273e-02 + 2.60145701e-02 0. 2.28928216e-02 0. 0. 2.08116556e-03 + 1.66493244e-02 0. 0. 0. 2.08116556e-03 0. 0. 0. 6.24349667e-03 + 3.12174833e-03 2.08116556e-03 0. 1.04058278e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. + 1.04058278e-03 1.04058278e-03 6.24349667e-03 8.32466222e-03 + 4.26638946e-02 0. 1.97710730e-02 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 8.32466222e-03 1.04058278e-03 1.04058278e-03 0. + 3.12174833e-03 0. 0. 4.16233111e-03 2.08116546e-02 4.57856432e-02 + 4.68262248e-02 3.12174833e-03 7.28407968e-03 2.08116556e-03 0. + 1.04058278e-03 2.08116556e-03 1.14464108e-02 7.28407968e-03 0. + 1.24869933e-02 1.24869933e-02 1.04058273e-02 2.39334032e-02 + 8.63683671e-02 8.22060406e-02 3.74609791e-02 2.08116556e-03 + 7.28407968e-03 1.35275759e-02 2.08116556e-03 9.36524477e-03 + 1.04058273e-02 3.12174833e-03 1.04058278e-03 0. 1.04058278e-03 + 2.08116556e-03 3.12174833e-03 1.76899079e-02 2.39334032e-02 + 3.01769003e-02 2.08116556e-03 1.04058278e-03 2.08116556e-03 + 6.24349667e-03 0. 2.08116556e-03 0. 1.04058273e-02 2.08116556e-03 + 0. 0. 1.66493244e-02 2.08116556e-03 3.22580673e-02 1.45681594e-02 + 3.12174833e-03 0. 0. 0. 2.08116556e-03 0. 2.08116556e-03 + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. + 5.20291366e-03 8.32466222e-03 2.08116556e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 2.08116556e-03 0. 4.16233111e-03 3.12174833e-03 + 0. 1.04058278e-03 8.32466222e-03 0. 1.76899079e-02 1.14464108e-02 + 1.14464108e-02 2.08116556e-03 1.04058278e-03 5.20291366e-03 + 2.08116556e-03 0. 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 + 0. 0. 2.08116556e-03 0. 2.08116556e-03 2.08116556e-03 + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. + 0. 0. 4.16233111e-03 0. 1.04058278e-03 1.04058278e-03 + 5.20291366e-03 5.20291366e-03 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 2.08116556e-03 0. 3.12174833e-03 0. + 1.45681594e-02 1.04058278e-03 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 5.20291366e-03 0. + 0. 0. 4.16233111e-03 0. 1.04058273e-02 5.20291366e-03 + 4.16233111e-03 1.04058273e-02 0. 5.20291366e-03 0. 2.08116556e-03 + 0. 6.24349667e-03 1.04058278e-03 2.08116556e-03 0. 0. 0. + 2.08116556e-03 1.04058278e-03 1.56087419e-02 2.08116556e-03 + 4.16233111e-03 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. + 2.08116556e-03 0. 0. 3.12174833e-03 1.04058278e-03 2.08116556e-03 + 3.12174833e-03 8.32466222e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 3.12174833e-03 + 7.28407968e-03 3.12174833e-03 8.32466222e-03 0. 9.36524477e-03 + 1.04058278e-03 1.04058278e-03 1.04058278e-03 8.32466222e-03 0. + 3.12174833e-03 0. 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. + 8.32466222e-03 3.12174833e-03 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. + 1.04058278e-03 6.24349667e-03 1.45681594e-02 2.39334032e-02 + 1.04058278e-03 1.45681594e-02 0. 0. 4.16233111e-03 1.76899079e-02 + 0. 2.08116556e-03 0. 3.12174833e-03 1.04058278e-03 2.08116556e-03 + 4.16233111e-03 2.39334032e-02 9.36524477e-03 1.24869933e-02 0. + 1.14464108e-02 1.04058278e-03 0. 2.08116556e-03 1.04058278e-03 + 1.24869933e-02 7.28407968e-03 2.08116556e-03 1.24869933e-02 + 8.32466222e-03 4.16233111e-03 2.91363187e-02 1.00936532e-01 + 7.59625435e-02 2.60145701e-02 1.04058278e-03 3.12174833e-03 + 5.20291366e-03 4.16233111e-03 4.16233111e-03 9.36524477e-03 + 4.16233111e-03 2.08116556e-03 0. 0. 5.20291366e-03 1.04058278e-03 + 3.12174833e-03 7.28407968e-03 1.66493244e-02 0. 3.12174833e-03 + 1.04058278e-03 3.12174833e-03 2.08116556e-03 8.32466222e-03 + 1.04058278e-03 4.16233111e-03 0. 0. 0. 2.08116546e-02 + 1.04058278e-03 2.39334032e-02 6.24349667e-03 3.12174833e-03 + 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 3.12174833e-03 3.12174833e-03 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 1.04058278e-03 2.08116556e-03 0. 0. 1.04058278e-03 + 2.08116556e-03 1.04058278e-03 1.97710730e-02 3.12174833e-03 + 6.24349667e-03 4.16233111e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 0. 0. 0. 0. 0. 1.04058278e-03 2.08116556e-03 0. 0. 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 2.08116556e-03 + 4.16233111e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 2.08116556e-03 5.20291366e-03 3.12174833e-03 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 2.08116556e-03 0. 0. 0. + 1.04058278e-03 0. 3.12174833e-03 2.08116556e-03 8.32466222e-03 + 9.36524477e-03 0. 3.12174833e-03 1.04058278e-03 1.04058278e-03 0. + 4.16233111e-03 1.04058278e-03 1.04058278e-03 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 7.28407968e-03 2.08116556e-03 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 2.08116556e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 7.28407968e-03 6.24349667e-03 + 2.08116556e-03 1.04058278e-03 0. 0. 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 3.12174833e-03 2.08116556e-03 0. 1.04058278e-03 0. 0. 0. + 1.04058278e-03 0. 4.16233111e-03 1.56087419e-02 2.70551518e-02 0. + 7.28407968e-03 2.08116556e-03 3.12174833e-03 0. 7.28407968e-03 + 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 0. + 0. 5.20291366e-03 0. 3.12174833e-03 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 4.16233111e-03 1.56087419e-02 1.01977110e-01 0. + 1.87304895e-02 1.04058278e-03 1.04058278e-03 0. 1.45681594e-02 + 2.08116556e-03 4.16233111e-03 0. 1.04058278e-03 2.08116556e-03 + 2.08116556e-03 1.04058278e-03 2.60145701e-02 8.22060406e-02 + 6.24349676e-02 0. 1.35275759e-02 0. 1.04058278e-03 2.08116556e-03 + 1.24869933e-02 6.24349667e-03 6.24349667e-03 0. 3.12174833e-03 + 5.20291366e-03 4.16233111e-03 1.76899079e-02 9.26118642e-02 + 2.28928216e-02 1.04058273e-02 1.04058278e-03 7.28407968e-03 + 6.24349667e-03 3.12174833e-03 4.16233111e-03 2.49739867e-02 + 1.04058278e-03 0. 0. 0. 3.12174833e-03 0. 1.04058273e-02 + 2.80957352e-02 5.20291366e-03 2.08116556e-03 1.04058278e-03 + 2.08116556e-03 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 + 7.28407968e-03 1.04058278e-03 0. 1.04058278e-03 2.39334032e-02 0. + 6.55567124e-02 2.80957352e-02 0. 0. 0. 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. + 0. 0. 0. 0. 0. 0. 1.87304895e-02 0. 0. 0. 2.08116546e-02 0. + 6.24349667e-03 8.32466222e-03 5.20291366e-03 2.08116556e-03 0. + 2.08116556e-03 1.04058278e-03 0. 1.04058278e-03 0. 3.12174833e-03 + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 3.12174833e-03 0. + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. + 1.04058278e-03 2.39334032e-02 2.08116556e-03 0. 0. 0. 0. 0. + 1.04058278e-03 2.49739867e-02 0. 3.12174833e-03 0. 2.39334032e-02 + 1.04058278e-03 9.36524477e-03 4.16233111e-03 0. 6.24349667e-03 + 1.04058278e-03 1.14464108e-02 1.04058278e-03 1.04058278e-03 0. + 3.32986489e-02 0. 0. 0. 0. 0. 0. 0. 1.56087419e-02 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 + 5.20291366e-03 4.16233111e-03 1.56087419e-02 0. 2.18522381e-02 0. + 0. 2.08116556e-03 2.08116546e-02 0. 0. 0. 0. 1.04058278e-03 0. 0. + 1.35275759e-02 0. 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 4.16233111e-03 1.76899079e-02 3.95421460e-02 + 1.04058278e-03 1.56087419e-02 0. 0. 0. 1.24869933e-02 0. 0. 0. 0. + 0. 0. 0. 7.28407968e-03 1.23829350e-01 4.68262248e-02 + 2.08116556e-03 8.32466222e-03 2.08116556e-03 0. 0. 3.12174833e-03 + 2.39334032e-02 5.20291366e-03 1.04058278e-03 7.28407968e-03 + 1.04058273e-02 3.12174833e-03 8.32466222e-03 4.26638946e-02 + 3.12174838e-02 4.99479733e-02 2.08116556e-03 9.36524477e-03 + 9.36524477e-03 1.04058278e-03 9.36524477e-03 2.49739867e-02 + 1.04058278e-03 1.04058278e-03 0. 0. 5.20291366e-03 0. + 2.39334032e-02 1.20707601e-01 3.22580673e-02 1.56087419e-02 + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 0. 3.12174833e-03 + 2.08116556e-03 1.04058278e-03 0. 1.04058278e-03 1.24869933e-02 0. + 1.12382941e-01 6.45161346e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 6.24349667e-03 0. 0. 0. 1.97710730e-02 0. 1.24869933e-02 + 5.20291366e-03 1.04058278e-03 2.08116556e-03 0. 2.08116556e-03 + 1.04058278e-03 0. 2.08116556e-03 2.08116556e-03 0. 0. 0. 0. + 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. + 3.12174833e-03 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. + 3.12174833e-03 0. 0. 1.04058278e-03 5.20291366e-03 0. + 2.08116556e-03 4.16233111e-03 1.04058278e-03 3.12174833e-03 0. + 8.32466222e-03 0. 0. 1.04058278e-03 1.35275759e-02 0. 0. 0. 0. 0. + 0. 0. 1.45681594e-02 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 1.04058273e-02 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. + 9.36524477e-03 1.04058278e-03 9.36524477e-03 0. 6.24349667e-03 0. + 0. 0. 8.32466222e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 9.36524477e-03 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 5.20291366e-03 + 5.20291366e-03 2.39334032e-02 0. 2.08116556e-03 2.08116556e-03 0. + 0. 6.24349667e-03 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. + 7.28407968e-03 3.22580673e-02 6.34755492e-02 1.14464108e-02 + 1.04058278e-03 2.08116556e-03 0. 0. 1.04058278e-03 2.08116556e-03 + 4.16233111e-03 3.12174833e-03 0. 4.16233111e-03 1.04058278e-03 + 1.04058278e-03 3.01769003e-02 4.99479733e-02 2.80957352e-02 + 3.64203975e-02 1.04058278e-03 6.24349667e-03 4.16233111e-03 + 4.16233111e-03 0. 1.66493244e-02 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 7.28407968e-03 3.22580673e-02 3.95421460e-02 + 6.24349667e-03 3.12174833e-03 1.04058278e-03 6.24349667e-03 + 3.12174833e-03 4.16233111e-03 2.08116556e-03 3.12174833e-03 0. 0. + 1.04058278e-03 3.32986489e-02 4.16233111e-03 7.28407949e-02 + 6.13943823e-02 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 2.08116556e-03 5.20291366e-03 2.08116556e-03 0. + 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 0. 1.04058278e-03 + 0. 0. 0. 0. 1.04058278e-03 1.04058273e-02 1.35275759e-02 + 4.16233111e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 2.08116556e-03 0. + 1.04058278e-03 3.12174833e-03 1.04058278e-03 1.04058278e-03 0. 0. + 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 + 1.45681594e-02 2.08116556e-03 0. 0. 7.28407968e-03 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 3.12174833e-03 1.04058278e-03 0. 0. + 1.14464108e-02 0. 1.45681594e-02 2.49739867e-02 0. 2.08116556e-03 + 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. + 0. 0. 0. 1.04058278e-03 2.08116556e-03 8.32466222e-03 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 5.20291366e-03 1.04058278e-03 1.14464108e-02 0. 0. + 1.04058278e-03 2.08116556e-03 0. 6.24349667e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 8.32466222e-03 0. 1.04058278e-03 0. 0. 0. + 2.08116556e-03 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. + 2.08116556e-03 1.35275759e-02 6.24349667e-03 1.46722168e-01 0. + 9.36524477e-03 0. 1.04058278e-03 0. 3.12174833e-03 1.04058278e-03 + 3.12174833e-03 0. 0. 1.04058278e-03 3.12174833e-03 3.12174833e-03 + 3.53798158e-02 1.14464108e-02 1.14464108e-02 0. 1.04058278e-03 + 2.08116556e-03 0. 0. 2.08116556e-03 1.04058278e-03 6.24349667e-03 + 0. 3.12174833e-03 1.24869933e-02 1.04058273e-02 3.01769003e-02 + 9.26118642e-02 6.24349667e-03 4.16233111e-03 0. 2.08116556e-03 + 8.32466222e-03 3.12174833e-03 0. 2.60145701e-02 0. 0. 0. 0. + 2.08116556e-03 0. 4.16233111e-03 8.32466222e-03 1.24869933e-02 + 1.04058278e-03 0. 0. 3.12174833e-03 2.08116556e-03 2.08116556e-03 + 1.04058278e-03 4.16233111e-03 0. 0. 0. 7.49219581e-02 + 2.08116556e-03 5.09885550e-02 4.57856432e-02 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 5.20291366e-03 0. 0. 0. 2.08116556e-03 + 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 1.04058278e-03 + 5.41103035e-02 0. 3.22580673e-02 2.18522381e-02 1.14464108e-02 + 3.12174833e-03 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 2.08116556e-03 0. 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 2.60145701e-02 0. 0. 0. 1.04058273e-02 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 1.56087419e-02 0. 0. 2.08116556e-03 + 7.70031288e-02 3.12174833e-03 2.18522381e-02 2.80957352e-02 + 1.04058278e-03 3.12174833e-03 0. 2.08116556e-03 0. 0. 0. + 1.14464108e-02 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 0. 0. 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 6.24349667e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 2.08116556e-03 8.32466222e-03 1.04058278e-03 3.22580673e-02 0. + 4.26638946e-02 0. 6.24349667e-03 0. 8.32466222e-03 0. 0. 0. 0. 0. + 0. 0. 6.24349667e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 4.16233111e-03 0. 9.36524477e-03 0. 4.89073917e-02 + 0. 1.76899079e-02 0. 1.04058278e-03 1.04058278e-03 4.16233111e-03 + 0. 0. 0. 1.04058278e-03 0. 0. 0. 5.20291366e-03 3.12174833e-03 + 1.56087419e-02 0. 6.24349667e-03 1.04058278e-03 5.20291366e-03 0. + 9.36524477e-03 5.20291366e-03 5.20291366e-03 0. 3.12174833e-03 + 9.36524477e-03 2.39334032e-02 1.14464108e-02 7.28407949e-02 + 7.28407968e-03 1.66493244e-02 0. 2.08116556e-03 1.04058278e-03 + 2.08116556e-03 4.16233111e-03 8.32466222e-03 0. 0. 0. 0. + 6.24349667e-03 0. 1.87304895e-02 5.72320521e-02 6.24349667e-03 + 9.36524477e-03 0. 1.04058278e-03 1.04058278e-03 0. 0. + 2.08116556e-03 6.24349667e-03 2.08116556e-03 0. 0. 1.24869933e-02 + 6.24349667e-03 6.03538007e-02 7.90842921e-02 1.04058278e-03 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 7.28407968e-03 1.04058278e-03 6.24349667e-03 4.16233111e-03 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 2.49739867e-02 0. 0. 0. 0. 0. 0. 0. 1.87304895e-02 + 0. 0. 0. 1.97710730e-02 0. 4.16233111e-03 2.08116556e-03 0. + 1.04058278e-03 0. 1.04058278e-03 0. 1.04058278e-03 0. + 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. 6.24349667e-03 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 2.08116556e-03 1.14464108e-02 0. + 2.08116556e-03 0. 1.04058278e-03 0. 8.32466222e-03 0. 0. 0. 0. 0. + 0. 0. 2.08116556e-03 0. 5.20291366e-03 0. 1.04058278e-03 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 1.66493244e-02 + 1.38397515e-01 0. 1.04058273e-02 0. 1.04058278e-03 0. + 8.32466222e-03 0. 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 + 6.24349667e-03 9.88553613e-02 1.42559841e-01 0. 4.16233111e-03 + 1.04058278e-03 2.08116556e-03 0. 6.24349667e-03 9.36524477e-03 + 8.32466222e-03 0. 4.16233111e-03 1.24869933e-02 1.14464108e-02 + 1.45681594e-02 3.43392305e-02 7.38813803e-02 4.05827276e-02 + 2.08116556e-03 6.24349667e-03 6.24349667e-03 1.04058278e-03 + 3.12174833e-03 4.16233111e-03 2.08116556e-03 0. 0. 0. + 3.12174833e-03 1.04058278e-03 2.60145701e-02 3.53798158e-02 + 4.16233093e-02 7.28407968e-03 2.08116556e-03 2.08116556e-03 + 4.16233111e-03 0. 5.20291366e-03 1.04058278e-03 6.24349667e-03 0. + 1.04058278e-03 0. 9.36524477e-03 1.04058278e-03 5.51508889e-02 + 2.70551518e-02 7.28407968e-03 3.12174833e-03 1.04058278e-03 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 3.12174833e-03 6.24349667e-03 0. + 1.04058278e-03 1.04058278e-03 0. 0. 2.08116556e-03 0. + 3.12174833e-03 0. 0. 0. 6.24349667e-03 0. 1.45681594e-02 + 6.24349667e-03 8.32466222e-03 5.20291366e-03 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 2.08116556e-03 7.28407968e-03 4.16233111e-03 + 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 2.08116556e-03 7.28407968e-03 2.08116556e-03 0. 0. + 0. 0. 0. 1.04058278e-03 4.16233111e-03 0. 0. 0. 4.16233111e-03 0. + 1.35275759e-02 3.12174833e-03 2.08116556e-03 2.08116556e-03 0. 0. + 0. 0. 1.04058278e-03 5.20291366e-03 0. 0. 0. 1.04058278e-03 0. 0. + 2.08116556e-03 4.16233111e-03 3.12174833e-03 4.16233111e-03 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 5.20291366e-03 + 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 0. 1.04058278e-03 0. 2.08116556e-03 8.32466222e-03 + 5.20291366e-03 1.14464108e-02 0. 7.28407968e-03 0. 0. 0. + 5.20291366e-03 0. 1.04058278e-03 0. 0. 2.08116556e-03 0. + 2.08116556e-03 1.14464108e-02 0. 1.04058278e-03 1.04058278e-03 0. + 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 1.04058278e-03 + 1.04058278e-03 2.08116556e-03 1.45681594e-02 5.51508889e-02 0. + 2.08116546e-02 3.12174833e-03 1.04058278e-03 1.04058278e-03 + 7.28407968e-03 2.08116556e-03 3.12174833e-03 0. 2.08116556e-03 0. + 2.08116556e-03 5.20291366e-03 3.74609791e-02 3.32986489e-02 + 1.97710730e-02 2.08116556e-03 4.16233111e-03 0. 0. 3.12174833e-03 + 2.08116556e-03 1.24869933e-02 1.45681594e-02 1.04058278e-03 + 5.20291366e-03 9.36524477e-03 3.12174833e-03 3.74609791e-02 + 9.05307010e-02 8.11654553e-02 3.12174838e-02 1.04058278e-03 + 1.35275759e-02 5.20291366e-03 1.04058278e-03 1.24869933e-02 + 8.32466222e-03 7.28407968e-03 2.08116556e-03 0. 0. 4.16233111e-03 + 1.04058278e-03 9.36524477e-03 2.49739867e-02 3.12174838e-02 + 7.28407968e-03 2.08116556e-03 1.04058278e-03 4.16233111e-03 0. + 4.16233111e-03 1.04058278e-03 5.20291366e-03 2.08116556e-03 0. + 1.04058278e-03 1.87304895e-02 0. 3.01769003e-02 1.35275759e-02 + 5.20291366e-03 0. 1.04058278e-03 2.08116556e-03 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 6.24349667e-03 3.12174833e-03 1.04058278e-03 0. 1.04058278e-03 0. + 1.04058278e-03 1.04058278e-03 5.20291366e-03 0. 0. 0. + 1.04058278e-03 0. 2.18522381e-02 1.04058273e-02 2.08116556e-03 + 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 7.28407968e-03 4.16233111e-03 + 1.04058278e-03 4.16233111e-03 2.08116556e-03 0. 1.04058278e-03 0. + 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 1.76899079e-02 + 2.08116556e-03 2.08116556e-03 2.08116556e-03 0. 0. 2.08116556e-03 + 0. 5.20291366e-03 1.04058278e-03 0. 0. 5.20291366e-03 0. + 9.36524477e-03 3.12174833e-03 7.28407968e-03 8.32466222e-03 0. + 6.24349667e-03 1.04058278e-03 1.04058278e-03 0. 4.16233111e-03 0. + 0. 0. 0. 0. 1.04058278e-03 3.12174833e-03 1.56087419e-02 + 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 + 0. 0. 1.04058278e-03 0. 5.20291366e-03 5.20291366e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 2.08116556e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 1.24869933e-02 7.28407968e-03 2.70551518e-02 + 1.04058278e-03 2.80957352e-02 0. 1.04058278e-03 0. 9.36524477e-03 + 2.08116556e-03 1.04058278e-03 0. 2.08116556e-03 1.04058278e-03 + 1.04058278e-03 2.08116556e-03 1.14464108e-02 2.08116556e-03 + 1.04058278e-03 0. 2.08116556e-03 0. 0. 0. 2.08116556e-03 + 2.08116556e-03 2.08116556e-03 0. 0. 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 2.08116556e-03 1.87304895e-02 2.39334032e-02 + 3.12174833e-03 2.49739867e-02 0. 0. 1.04058278e-03 9.36524477e-03 + 0. 2.08116556e-03 0. 1.04058278e-03 2.08116556e-03 1.04058278e-03 + 2.08116556e-03 1.97710730e-02 1.76899079e-02 1.14464108e-02 + 1.04058278e-03 8.32466222e-03 1.04058278e-03 0. 0. 1.04058273e-02 + 1.45681594e-02 8.32466222e-03 3.12174833e-03 8.32466222e-03 + 4.16233111e-03 7.28407968e-03 3.01769003e-02 9.67741981e-02 + 2.60145701e-02 3.22580673e-02 0. 4.16233111e-03 3.12174833e-03 + 1.04058278e-03 3.12174833e-03 2.08116556e-03 3.12174833e-03 + 1.04058278e-03 0. 0. 2.08116556e-03 0. 4.16233111e-03 + 3.12174838e-02 3.64203975e-02 1.04058273e-02 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 2.08116556e-03 1.04058278e-03 0. + 1.04058278e-03 1.04058273e-02 5.20291366e-03 1.87304895e-02 + 1.24869933e-02 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 9.36524477e-03 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 0. 5.20291366e-03 + 0. 6.24349667e-03 3.12174833e-03 8.32466222e-03 0. 0. + 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 2.08116556e-03 0. 9.36524477e-03 2.08116556e-03 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 4.57856432e-02 2.08116556e-03 0. 0. 0. 0. 0. 0. + 2.49739867e-02 0. 0. 0. 4.16233111e-03 1.04058278e-03 + 1.04058273e-02 0. 0. 3.12174833e-03 0. 2.08116556e-03 0. 0. 0. + 4.16233111e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 6.24349667e-03 + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 2.08116556e-03 5.20291366e-03 1.24869933e-02 0. + 3.12174833e-03 1.04058278e-03 3.12174833e-03 0. 4.16233111e-03 0. + 0. 0. 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. + 1.04058278e-03 2.08116556e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 0. 0. 2.08116556e-03 0. 2.39334032e-02 + 5.41103035e-02 0. 9.36524477e-03 0. 1.04058278e-03 0. + 8.32466222e-03 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 3.12174833e-03 2.39334032e-02 1.51925087e-01 1.06139444e-01 + 2.08116556e-03 9.36524477e-03 1.04058278e-03 2.08116556e-03 + 3.12174833e-03 7.28407968e-03 4.47450578e-02 1.24869933e-02 0. + 3.12174833e-03 6.24349667e-03 6.24349667e-03 3.32986489e-02 + 5.82726374e-02 1.76899079e-02 1.14464108e-02 0. 5.20291366e-03 + 1.04058273e-02 0. 3.12174833e-03 2.70551518e-02 0. 0. 0. 0. + 6.24349667e-03 0. 3.12174833e-03 2.91363187e-02 1.66493244e-02 + 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. 0. 4.16233111e-03 0. 0. + 0. 9.36524477e-03 3.12174833e-03 2.08116546e-02 1.97710730e-02 + 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 1.04058278e-03 4.16233111e-03 0. 0. 0. + 2.08116556e-03 0. 1.04058278e-03 0. 1.45681594e-02 1.04058278e-03 + 1.04058278e-03 0. 3.12174838e-02 0. 3.12174833e-03 6.24349667e-03 + 1.66493244e-02 5.20291366e-03 0. 2.08116556e-03 4.16233111e-03 0. + 1.04058278e-03 0. 2.08116556e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. + 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 0. 0. 1.66493244e-02 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 3.95421460e-02 2.08116556e-03 + 2.08116556e-03 0. 3.12174833e-03 0. 0. 1.04058278e-03 + 4.57856432e-02 1.04058278e-03 0. 0. 3.32986489e-02 0. + 7.28407968e-03 2.08116556e-03 0. 7.28407968e-03 0. 1.24869933e-02 + 0. 0. 0. 3.22580673e-02 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 1.24869933e-02 0. 1.04058278e-03 0. 2.08116556e-03 + 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 7.28407968e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. 1.45681594e-02 + 3.12174833e-03 2.60145701e-02 0. 4.47450578e-02 0. 1.04058278e-03 + 1.04058278e-03 2.80957352e-02 0. 0. 0. 0. 0. 0. 0. 1.24869933e-02 + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 2.08116556e-03 0. 1.04058278e-03 0. 4.16233111e-03 1.45681594e-02 + 2.60145701e-02 0. 1.04058273e-02 0. 0. 0. 8.32466222e-03 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 1.35275759e-02 + 4.05827276e-02 4.37044762e-02 1.04058278e-03 7.28407968e-03 0. 0. + 1.04058278e-03 2.08116556e-03 3.22580673e-02 1.56087419e-02 0. + 2.60145701e-02 1.35275759e-02 1.24869933e-02 5.20291366e-03 + 4.47450578e-02 5.82726374e-02 5.72320521e-02 1.04058278e-03 + 4.16233111e-03 2.08116556e-03 0. 4.16233111e-03 1.24869933e-02 + 1.04058278e-03 3.12174833e-03 0. 0. 7.28407968e-03 1.04058278e-03 + 2.08116546e-02 3.22580673e-02 5.20291403e-02 1.56087419e-02 + 2.08116556e-03 2.08116556e-03 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 4.16233111e-03 1.04058273e-02 0. 1.04058278e-03 + 1.04058278e-03 2.08116546e-02 2.08116556e-03 1.15504690e-01 + 2.91363187e-02 0. 3.12174833e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 2.08116556e-03 0. 0. 0. 0. + 1.04058278e-03 0. 4.16233111e-03 0. 0. 0. 3.12174833e-03 0. + 1.04058273e-02 9.36524477e-03 2.08116556e-03 1.04058278e-03 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 3.12174833e-03 1.04058278e-03 1.04058278e-03 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 5.20291366e-03 6.24349667e-03 2.08116556e-03 + 1.04058278e-03 3.12174833e-03 0. 0. 0. 0. 2.08116556e-03 0. 0. + 1.04058278e-03 0. 0. 9.36524477e-03 6.24349667e-03 1.04058278e-03 + 7.28407968e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 0. 0. 0. 0. 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 0. 0. 1.04058278e-03 2.08116556e-03 2.08116556e-03 + 4.16233111e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 5.20291366e-03 9.36524477e-03 0. 1.04058278e-03 0. + 0. 0. 4.16233111e-03 0. 2.08116556e-03 0. 0. 0. 1.04058278e-03 + 3.12174833e-03 1.14464108e-02 1.04058278e-03 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. + 3.12174833e-03 4.16233111e-03 8.32466222e-03 4.37044762e-02 + 1.04058278e-03 1.66493244e-02 1.04058278e-03 2.08116556e-03 + 2.08116556e-03 3.12174833e-03 1.04058278e-03 4.16233111e-03 0. 0. + 0. 1.04058278e-03 2.08116556e-03 5.51508889e-02 4.89073917e-02 + 1.76899079e-02 0. 2.08116556e-03 2.08116556e-03 0. 3.12174833e-03 + 3.12174833e-03 1.04058278e-03 3.12174833e-03 0. 4.16233111e-03 + 2.08116556e-03 4.16233111e-03 5.09885550e-02 8.32466185e-02 + 1.97710730e-02 4.57856432e-02 0. 1.04058278e-03 9.36524477e-03 + 5.20291366e-03 5.20291366e-03 3.74609791e-02 0. 1.04058278e-03 0. + 0. 0. 0. 5.20291366e-03 3.95421460e-02 2.60145701e-02 + 1.76899079e-02 0. 2.08116556e-03 6.24349667e-03 1.04058278e-03 + 2.08116556e-03 1.14464108e-02 1.04058278e-03 0. 0. 0. + 3.53798158e-02 1.04058278e-03 3.53798158e-02 9.46930349e-02 0. 0. + 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 1.04058278e-03 4.16233111e-03 0. 8.32466222e-03 + 2.08116546e-02 2.08116556e-03 2.08116556e-03 0. 0. 0. 0. + 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 2.08116556e-03 4.16233111e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 1.04058273e-02 2.08116556e-03 0. 0. + 3.12174833e-03 0. 2.08116556e-03 0. 1.04058278e-03 0. 0. 0. + 3.32986489e-02 1.04058278e-03 1.45681594e-02 2.08116546e-02 + 2.08116556e-03 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. + 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. 1.04058273e-02 0. + 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 0. 2.08116556e-03 9.36524477e-03 0. 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 6.24349667e-03 0. 1.45681594e-02 0. + 3.12174833e-03 0. 4.16233111e-03 1.04058278e-03 1.04058273e-02 0. + 0. 0. 0. 0. 0. 0. 1.56087419e-02 2.08116556e-03 2.08116556e-03 0. + 0. 0. 0. 0. 1.04058278e-03 2.08116556e-03 0. 0. 0. 2.08116556e-03 + 1.04058278e-03 0. 2.80957352e-02 2.08116556e-03 6.03538007e-02 0. + 4.16233111e-03 0. 2.08116556e-03 0. 1.24869933e-02 0. 0. 0. 0. 0. + 0. 0. 3.64203975e-02 1.97710730e-02 1.56087419e-02 2.08116556e-03 + 8.32466222e-03 1.04058278e-03 4.16233111e-03 0. 1.45681594e-02 + 1.04058278e-03 5.20291366e-03 0. 2.08116556e-03 8.32466222e-03 + 6.24349667e-03 1.24869933e-02 1.00936532e-01 1.14464108e-02 + 1.45681594e-02 1.04058278e-03 3.12174833e-03 8.32466222e-03 + 1.04058278e-03 1.04058278e-03 2.28928216e-02 0. 0. 0. 0. + 1.04058278e-03 0. 4.16233111e-03 1.24869933e-02 1.45681594e-02 + 3.12174833e-03 0. 0. 2.08116556e-03 1.04058278e-03 0. + 3.12174833e-03 0. 1.04058278e-03 0. 0. 2.80957352e-02 0. + 7.18002096e-02 8.32466185e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 0. 0. 1.04058278e-03 0. + 0. 0. 0. 0. 0. 0. 1.24869933e-02 1.04058278e-03 1.14464108e-02 + 1.35275759e-02 1.14464108e-02 2.08116556e-03 0. 0. 1.04058278e-03 + 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 3.12174833e-03 2.08116556e-03 2.08116556e-03 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 7.28407968e-03 3.12174833e-03 0. 0. 1.04058278e-03 0. + 1.04058278e-03 3.12174833e-03 3.12174833e-03 0. 0. 0. + 1.35275759e-02 0. 7.28407968e-03 1.45681594e-02 0. 7.28407968e-03 + 0. 2.08116556e-03 0. 0. 0. 9.36524477e-03 0. 0. 0. 0. 0. + 2.08116556e-03 0. 2.08116556e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 7.28407968e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 7.28407968e-03 2.08116556e-03 + 4.26638946e-02 0. 1.66493244e-02 0. 3.12174833e-03 0. + 4.47450578e-02 0. 0. 0. 0. 0. 2.08116556e-03 0. 6.24349667e-03 + 1.04058278e-03 3.12174833e-03 0. 1.04058278e-03 0. 0. 0. + 3.12174833e-03 0. 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 + 1.76899079e-02 7.28407968e-03 1.54006258e-01 0. 2.60145701e-02 0. + 1.04058278e-03 0. 1.14464108e-02 0. 0. 0. 0. 0. 0. 3.12174833e-03 + 7.28407968e-03 7.28407968e-03 3.95421460e-02 0. 1.35275759e-02 0. + 1.04058278e-03 0. 1.87304895e-02 2.08116556e-03 6.24349667e-03 0. + 1.04058278e-03 7.28407968e-03 4.16233111e-03 1.35275759e-02 + 7.28407949e-02 1.76899079e-02 1.56087419e-02 2.08116556e-03 + 4.16233111e-03 2.08116556e-03 0. 1.04058278e-03 3.01769003e-02 0. + 0. 0. 0. 0. 0. 1.56087419e-02 7.70031288e-02 6.24349667e-03 + 1.14464108e-02 0. 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 + 0. 2.08116556e-03 2.08116556e-03 0. 1.04058278e-03 1.04058273e-02 + 2.08116556e-03 3.64203975e-02 5.61914705e-02 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 9.36524477e-03 0. 1.04058278e-03 0. 0. + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 8.32466222e-03 + 2.08116556e-03 6.24349667e-03 1.04058278e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 4.16233111e-03 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 1.35275759e-02 1.04058278e-03 0. 0. 2.08116556e-03 0. 0. 0. + 3.12174833e-03 0. 0. 0. 7.28407968e-03 0. 8.32466222e-03 + 3.12174833e-03 0. 2.08116556e-03 0. 3.12174833e-03 1.04058278e-03 + 1.04058278e-03 0. 4.68262248e-02 0. 0. 0. 0. 0. 0. 0. + 1.24869933e-02 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 1.24869933e-02 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 1.04058278e-03 1.97710730e-02 0. 1.14464108e-02 + 1.04058278e-03 1.04058278e-03 0. 7.28407968e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 5.20291366e-03 0. 2.08116556e-03 0. 0. + 2.08116556e-03 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 1.04058278e-03 1.76899079e-02 5.41103035e-02 + 0. 4.16233111e-03 0. 0. 2.08116556e-03 2.08116556e-03 0. 0. 0. 0. + 0. 1.04058278e-03 3.12174833e-03 1.14464108e-02 1.57128006e-01 + 1.27991676e-01 0. 2.08116556e-03 1.04058278e-03 0. 1.04058278e-03 + 3.12174833e-03 1.56087419e-02 7.28407968e-03 0. 2.08116556e-03 + 7.28407968e-03 5.20291366e-03 1.66493244e-02 3.53798158e-02 + 8.74089524e-02 4.37044762e-02 4.16233111e-03 3.12174833e-03 + 4.16233111e-03 3.12174833e-03 4.16233111e-03 8.32466222e-03 + 3.12174833e-03 1.04058278e-03 0. 0. 6.24349667e-03 5.20291366e-03 + 1.35275759e-02 3.53798158e-02 3.53798158e-02 5.20291366e-03 + 1.04058278e-03 2.08116556e-03 2.08116556e-03 0. 0. 0. + 1.04058273e-02 0. 1.04058278e-03 0. 1.66493244e-02 2.08116556e-03 + 5.93132190e-02 1.66493244e-02 0. 1.04058278e-03 0. 1.04058278e-03 + 2.08116556e-03 0. 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. + 2.08116556e-03 1.04058278e-03 2.08116556e-03 3.12174833e-03 + 2.08116556e-03 0. 3.12174833e-03 0. 2.08116556e-03 0. + 2.08116556e-03 0. 1.04058278e-03 3.12174833e-03 4.16233111e-03 0. + 1.66493244e-02 4.16233111e-03 7.28407968e-03 7.28407968e-03 0. + 2.08116556e-03 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. + 1.04058278e-03 0. 0. 2.08116556e-03 4.16233111e-03 1.04058278e-03 + 0. 0. 0. 0. 0. 0. 4.16233111e-03 0. 0. 0. 0. 0. 2.08116556e-03 0. + 8.32466222e-03 4.16233111e-03 0. 3.12174833e-03 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 2.08116556e-03 + 9.36524477e-03 1.04058278e-03 0. 0. 2.08116556e-03 0. 0. 0. + 8.32466222e-03 2.08116556e-03 1.04058278e-03 1.04058278e-03 + 4.16233111e-03 1.04058278e-03 1.97710730e-02 9.36524477e-03 + 1.04058278e-03 4.16233111e-03 0. 3.12174833e-03 0. 0. 0. + 4.16233111e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 1.04058273e-02 + 2.08116556e-03 3.12174833e-03 0. 2.08116556e-03 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 2.08116556e-03 0. + 0. 4.16233111e-03 6.24349667e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 3.12174833e-03 0. 2.08116556e-03 1.14464108e-02 3.12174833e-03 + 9.36524477e-03 0. 6.24349667e-03 0. 0. 0. 2.08116556e-03 0. + 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 2.08116556e-03 + 7.28407968e-03 4.16233111e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 0. 1.04058278e-03 0. 2.08116556e-03 + 2.08116556e-03 1.14464108e-02 3.43392305e-02 0. 1.24869933e-02 + 2.08116556e-03 0. 2.08116556e-03 1.14464108e-02 1.04058278e-03 + 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 1.04058278e-03 + 8.32466222e-03 2.91363187e-02 2.80957352e-02 1.04058273e-02 0. + 6.24349667e-03 0. 0. 3.12174833e-03 1.04058278e-03 1.35275759e-02 + 1.35275759e-02 1.04058278e-03 5.20291366e-03 6.24349667e-03 + 6.24349667e-03 3.74609791e-02 9.05307010e-02 8.01248774e-02 + 3.64203975e-02 2.08116556e-03 7.28407968e-03 8.32466222e-03 + 2.08116556e-03 4.16233111e-03 1.56087419e-02 3.12174833e-03 + 2.08116556e-03 0. 1.04058278e-03 2.08116556e-03 3.12174833e-03 + 1.35275759e-02 3.32986489e-02 4.16233093e-02 3.12174833e-03 + 3.12174833e-03 3.12174833e-03 3.12174833e-03 1.04058278e-03 + 1.04058278e-03 2.08116556e-03 5.20291366e-03 0. 1.04058278e-03 0. + 9.36524477e-03 2.08116556e-03 2.60145701e-02 1.66493244e-02 + 3.12174833e-03 2.08116556e-03 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 9.36524477e-03 3.12174833e-03 1.04058278e-03 1.04058278e-03 0. 0. + 1.04058278e-03 0. 3.12174833e-03 0. 0. 0. 2.08116556e-03 0. + 7.28407968e-03 6.24349667e-03 1.04058273e-02 2.08116556e-03 + 1.04058278e-03 0. 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 0. 2.08116556e-03 1.04058278e-03 5.20291366e-03 + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 3.12174833e-03 3.12174833e-03 0. 0. 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 1.56087419e-02 3.12174833e-03 1.04058278e-03 0. 1.04058278e-03 0. + 1.04058278e-03 0. 7.28407968e-03 0. 0. 1.04058278e-03 + 2.08116556e-03 0. 8.32466222e-03 6.24349667e-03 3.12174833e-03 + 9.36524477e-03 1.04058278e-03 4.16233111e-03 0. 4.16233111e-03 0. + 1.24869933e-02 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 1.56087419e-02 2.08116556e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. + 2.08116556e-03 0. 0. 2.08116556e-03 0. 3.12174833e-03 + 9.36524477e-03 2.08116556e-03 1.04058278e-03 0. 0. 1.04058278e-03 + 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 8.32466222e-03 + 8.32466222e-03 1.24869933e-02 0. 0. 2.08116556e-03 1.04058278e-03 + 1.04058278e-03 5.20291366e-03 1.04058278e-03 0. 0. 0. + 1.04058278e-03 1.04058278e-03 2.08116556e-03 6.24349667e-03 + 4.16233111e-03 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 2.08116556e-03 + 3.12174833e-03 1.87304895e-02 1.76899079e-02 0. 8.32466222e-03 + 1.04058278e-03 4.16233111e-03 1.04058278e-03 1.35275759e-02 + 2.08116556e-03 5.20291366e-03 0. 3.12174833e-03 1.04058278e-03 + 1.04058278e-03 6.24349667e-03 3.12174838e-02 4.78668064e-02 + 2.08116546e-02 2.08116556e-03 7.28407968e-03 0. 0. 2.08116556e-03 + 8.32466222e-03 1.45681594e-02 7.28407968e-03 3.12174833e-03 + 9.36524477e-03 1.24869933e-02 9.36524477e-03 3.32986489e-02 + 9.67741981e-02 3.22580673e-02 4.16233093e-02 0. 8.32466222e-03 + 8.32466222e-03 1.04058278e-03 4.16233111e-03 2.08116546e-02 + 1.04058278e-03 1.04058278e-03 0. 0. 6.24349667e-03 0. + 7.28407968e-03 4.78668064e-02 3.32986489e-02 1.56087419e-02 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 2.08116556e-03 0. 0. 1.14464108e-02 0. 1.14464108e-02 + 1.66493244e-02 2.08116556e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 1.04058278e-03 7.28407968e-03 1.04058278e-03 0. + 0. 0. 0. 2.08116556e-03 0. 0. 1.04058278e-03 0. 0. 3.12174833e-03 + 0. 7.28407968e-03 4.16233111e-03 4.16233111e-03 4.16233111e-03 0. + 1.04058278e-03 3.12174833e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. + 0. 0. 0. 2.08116556e-03 0. 5.20291366e-03 2.08116556e-03 0. 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 3.12174833e-03 2.18522381e-02 3.12174833e-03 0. 0. 0. 0. + 1.04058278e-03 0. 1.45681594e-02 0. 1.04058278e-03 0. + 4.16233111e-03 2.08116556e-03 6.24349667e-03 0. 1.04058278e-03 + 8.32466222e-03 0. 2.08116556e-03 0. 1.04058278e-03 0. + 5.20291366e-03 0. 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 + 7.28407968e-03 1.04058278e-03 3.12174833e-03 0. 2.08116556e-03 0. + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 1.14464108e-02 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 4.16233111e-03 2.08116556e-03 2.60145701e-02 0. 1.24869933e-02 + 1.04058278e-03 0. 1.04058278e-03 1.04058273e-02 0. 0. 0. 0. 0. 0. + 0. 1.35275759e-02 2.08116556e-03 5.20291366e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. + 3.12174833e-03 1.56087419e-02 8.42872038e-02 0. 9.36524477e-03 0. + 0. 2.08116556e-03 1.45681594e-02 0. 0. 0. 0. 0. 0. 8.32466222e-03 + 3.74609791e-02 8.63683671e-02 5.30697219e-02 1.04058278e-03 + 1.66493244e-02 1.04058278e-03 0. 1.04058278e-03 5.20291366e-03 + 2.08116546e-02 8.32466222e-03 1.04058278e-03 5.20291366e-03 + 7.28407968e-03 4.16233111e-03 2.80957352e-02 6.45161346e-02 + 1.97710730e-02 3.12174833e-03 0. 2.08116556e-03 1.04058273e-02 0. + 1.04058278e-03 7.28407968e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 4.16233111e-03 1.14464108e-02 0. 0. 0. 3.12174833e-03 0. + 2.08116556e-03 2.08116556e-03 2.08116556e-03 0. 0. 1.04058278e-03 + 5.20291366e-03 1.04058278e-03 1.45681594e-02 6.24349667e-03 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 8.32466222e-03 0. + 0. 0. 1.76899079e-02 0. 8.32466222e-03 6.24349667e-03 + 2.49739867e-02 1.04058278e-03 0. 1.04058278e-03 8.32466222e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 1.24869933e-02 1.04058278e-03 + 0. 0. 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. + 0. 0. 0. 0. 5.82726374e-02 2.08116556e-03 0. 0. 2.08116556e-03 0. + 2.08116556e-03 1.04058278e-03 4.78668064e-02 0. 0. 0. + 2.18522381e-02 1.04058278e-03 3.12174833e-03 0. 0. 6.24349667e-03 + 0. 3.12174833e-03 1.04058278e-03 0. 0. 1.04058273e-02 0. 0. 0. 0. + 0. 0. 0. 5.20291366e-03 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 7.28407968e-03 + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. + 5.20291366e-03 1.35275759e-02 2.70551518e-02 0. 2.08116546e-02 + 1.04058278e-03 1.04058278e-03 0. 1.14464108e-02 1.04058278e-03 0. + 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. + 0. 0. 5.20291366e-03 1.04058278e-03 2.08116556e-03 1.66493244e-02 + 6.24349676e-02 0. 2.18522381e-02 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 8.32466222e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 7.28407968e-03 1.21748187e-01 7.80437067e-02 + 0. 1.87304895e-02 1.04058278e-03 3.12174833e-03 1.04058278e-03 + 7.28407968e-03 3.95421460e-02 3.85015644e-02 0. 3.12174838e-02 + 9.36524477e-03 7.28407968e-03 8.32466222e-03 3.64203975e-02 + 3.43392305e-02 1.97710730e-02 0. 1.04058278e-03 3.12174833e-03 + 5.20291366e-03 4.16233111e-03 2.28928216e-02 1.04058278e-03 0. 0. + 0. 1.04058278e-03 0. 1.35275759e-02 2.60145701e-02 5.41103035e-02 + 1.56087419e-02 0. 1.04058278e-03 2.08116556e-03 0. 2.08116556e-03 + 0. 3.12174833e-03 1.04058278e-03 2.08116556e-03 0. 5.20291366e-03 + 0. 2.28928216e-02 1.24869933e-02 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 6.24349667e-03 2.08116556e-03 1.04058278e-03 0. 2.08116556e-03 0. + 2.08116556e-03 1.04058278e-03 0. 0. 1.04058278e-03 0. + 8.32466222e-03 1.04058278e-03 3.12174833e-03 4.16233111e-03 + 1.35275759e-02 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 3.12174833e-03 0. + 1.04058278e-03 0. 4.16233111e-03 1.04058278e-03 1.04058278e-03 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 1.04058278e-03 1.76899079e-02 2.08116556e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 1.45681594e-02 0. 0. 1.04058278e-03 + 9.36524477e-03 0. 7.28407968e-03 0. 2.08116556e-03 5.20291366e-03 + 0. 2.08116556e-03 0. 0. 0. 3.32986489e-02 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.35275759e-02 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 0. 6.24349667e-03 5.20291366e-03 8.32466222e-03 0. + 2.08116556e-03 1.04058278e-03 0. 0. 6.24349667e-03 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 2.08116556e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 3.12174833e-03 0. + 0. 0. 0. 0. 4.16233111e-03 2.18522381e-02 5.09885550e-02 0. + 5.20291366e-03 0. 2.08116556e-03 0. 6.24349667e-03 1.04058278e-03 + 0. 0. 0. 2.08116556e-03 2.08116556e-03 8.32466222e-03 + 2.49739867e-02 1.19667016e-01 8.01248774e-02 0. 4.16233111e-03 + 1.04058278e-03 2.08116556e-03 0. 3.12174833e-03 3.22580673e-02 + 1.56087419e-02 0. 7.28407968e-03 1.04058273e-02 3.12174833e-03 + 3.43392305e-02 6.86784610e-02 2.28928216e-02 1.14464108e-02 + 1.04058278e-03 7.28407968e-03 1.14464108e-02 0. 4.16233111e-03 + 4.57856432e-02 1.04058278e-03 0. 0. 0. 5.20291366e-03 + 1.04058278e-03 7.28407968e-03 1.56087419e-02 1.87304895e-02 + 8.32466222e-03 1.04058278e-03 1.04058278e-03 3.12174833e-03 0. + 1.04058278e-03 1.04058278e-03 6.24349667e-03 0. 0. 0. + 4.26638946e-02 1.04058278e-03 5.82726374e-02 4.16233093e-02 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 7.28407968e-03 0. 0. + 1.04058278e-03 2.39334032e-02 1.04058278e-03 1.45681594e-02 + 1.87304895e-02 2.08116556e-03 1.04058278e-03 0. 0. 2.08116556e-03 + 0. 1.04058278e-03 4.16233111e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 3.12174833e-03 0. 2.08116556e-03 1.04058278e-03 1.04058278e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 5.20291366e-03 0. 2.08116556e-03 0. 0. 0. 1.04058278e-03 0. + 7.59625435e-02 0. 1.04058278e-03 1.04058278e-03 5.61914705e-02 0. + 2.39334032e-02 1.66493244e-02 0. 4.16233111e-03 0. 6.24349667e-03 + 0. 0. 0. 8.42872038e-02 0. 1.04058278e-03 0. 0. 0. 0. 0. + 2.28928216e-02 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 1.35275759e-02 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 1.56087419e-02 1.04058278e-03 + 1.04058273e-02 0. 6.24349667e-03 0. 1.04058278e-03 0. + 3.12174838e-02 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 9.36524477e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 5.20291366e-03 + 3.12174833e-03 3.85015644e-02 0. 8.32466222e-03 0. 0. 0. + 4.16233111e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.66493244e-02 + 9.36524477e-03 1.24869933e-02 0. 3.12174833e-03 1.04058278e-03 0. + 0. 3.12174833e-03 1.04058278e-03 1.04058278e-03 0. 5.20291366e-03 + 6.24349667e-03 3.12174833e-03 1.45681594e-02 4.57856432e-02 + 2.60145701e-02 2.49739867e-02 4.16233111e-03 2.08116556e-03 + 1.04058278e-03 0. 5.20291366e-03 1.24869933e-02 1.04058278e-03 0. + 0. 0. 3.12174833e-03 1.04058278e-03 4.16233111e-03 1.35275759e-02 + 2.18522381e-02 8.32466222e-03 0. 1.04058278e-03 3.12174833e-03 0. + 2.08116556e-03 4.16233111e-03 4.16233111e-03 1.04058278e-03 0. 0. + 4.99479733e-02 2.08116556e-03 1.51925087e-01 3.64203975e-02 + 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 2.08116556e-03 3.12174833e-03 0. 0. + 1.04058278e-03 0. 2.08116556e-03 0. 6.24349667e-03 0. 0. 0. + 3.64203975e-02 0. 3.85015644e-02 8.32466222e-03 4.16233111e-03 + 2.08116556e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 0. 9.36524477e-03 1.04058278e-03 0. 1.04058278e-03 + 1.04058278e-03 0. 1.04058278e-03 0. 7.28407968e-03 1.04058278e-03 + 0. 0. 1.56087419e-02 0. 1.35275759e-02 0. 0. 4.16233111e-03 0. + 4.16233111e-03 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 3.12174833e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 1.04058278e-03 + 4.16233111e-03 1.04058278e-03 3.95421460e-02 0. 3.32986489e-02 0. + 0. 0. 1.04058273e-02 0. 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. + 1.66493244e-02 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 1.14464108e-02 + 6.24349667e-03 9.98959467e-02 0. 3.12174838e-02 0. 1.04058278e-03 + 0. 1.45681594e-02 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 1.66493244e-02 1.04058273e-02 1.76899079e-02 0. 8.32466222e-03 + 1.04058278e-03 0. 0. 3.12174833e-03 2.08116556e-03 7.28407968e-03 + 0. 2.08116556e-03 4.16233111e-03 3.12174833e-03 1.56087419e-02 + 4.99479733e-02 1.24869933e-02 2.70551518e-02 0. 0. 2.08116556e-03 + 0. 0. 4.16233111e-03 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. + 1.87304895e-02 1.38397515e-01 1.97710730e-02 2.49739867e-02 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 2.08116556e-03 2.08116556e-03 + 0. 0. 7.28407968e-03 1.04058278e-03 4.78668064e-02 4.78668064e-02 + 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 4.16233111e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. + 3.12174833e-03 0. 0. 0. 1.04058278e-03 0. 0. 5.20291366e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 9.36524477e-03 + 2.08116556e-03 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 4.16233111e-03 0. 0. 0. 1.04058278e-03 0. 5.20291366e-03 + 3.12174833e-03 1.04058278e-03 4.16233111e-03 0. 3.12174833e-03 0. + 2.08116556e-03 0. 8.32466222e-03 0. 0. 0. 0. 0. 0. 0. + 8.32466222e-03 0. 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 4.16233111e-03 8.32466222e-03 0. 1.04058273e-02 0. + 1.04058278e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 4.16233111e-03 1.04058278e-03 5.20291366e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 4.16233111e-03 1.45681594e-02 4.05827276e-02 0. + 6.24349667e-03 0. 0. 1.04058278e-03 4.16233111e-03 0. 0. 0. 0. 0. + 1.04058278e-03 3.12174833e-03 2.49739867e-02 1.88345477e-01 + 1.33194596e-01 0. 2.08116556e-03 1.04058278e-03 0. 1.04058278e-03 + 1.04058278e-03 5.20291366e-03 3.12174833e-03 1.04058278e-03 + 1.04058278e-03 9.36524477e-03 1.04058278e-03 1.97710730e-02 + 4.47450578e-02 5.72320521e-02 5.20291403e-02 1.04058278e-03 + 7.28407968e-03 5.20291366e-03 2.08116556e-03 3.12174833e-03 + 1.56087419e-02 0. 2.08116556e-03 0. 0. 8.32466222e-03 + 4.16233111e-03 1.76899079e-02 4.05827276e-02 3.74609791e-02 + 7.28407968e-03 2.08116556e-03 2.08116556e-03 3.12174833e-03 0. + 1.04058278e-03 5.20291366e-03 9.36524477e-03 3.12174833e-03 + 2.08116556e-03 1.04058278e-03 2.28928216e-02 1.04058278e-03 + 4.89073917e-02 2.39334032e-02 0. 1.04058278e-03 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 1.04058273e-02 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 2.08116556e-03 0. 1.04058278e-03 2.08116556e-03 + 3.12174833e-03 0. 0. 0. 8.32466222e-03 0. 1.14464108e-02 + 8.32466222e-03 8.32466222e-03 3.12174833e-03 0. 3.12174833e-03 0. + 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. + 5.20291366e-03 2.08116556e-03 1.04058278e-03 1.04058278e-03 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 + 1.04058278e-03 9.36524477e-03 1.04058278e-03 1.04058278e-03 0. 0. + 0. 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 3.12174833e-03 + 2.08116556e-03 8.32466222e-03 4.16233111e-03 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 2.08116556e-03 + 0. 8.32466222e-03 0. 2.08116556e-03 9.36524477e-03 0. + 4.16233111e-03 1.04058278e-03 0. 0. 2.08116556e-03 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.14464108e-02 6.24349667e-03 2.08116556e-03 + 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 1.04058278e-03 2.08116556e-03 9.36524477e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 2.08116556e-03 2.08116556e-03 1.24869933e-02 7.28407968e-03 + 1.66493244e-02 0. 9.36524477e-03 0. 0. 0. 4.16233111e-03 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 3.12174833e-03 + 1.14464108e-02 4.16233111e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 0. 1.04058278e-03 2.08116556e-03 0. + 0. 4.16233111e-03 1.35275759e-02 2.18522381e-02 0. 1.04058273e-02 + 1.04058278e-03 1.04058278e-03 1.04058278e-03 1.14464108e-02 + 2.08116556e-03 2.08116556e-03 0. 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 2.08116556e-03 5.61914705e-02 2.08116546e-02 + 1.35275759e-02 3.12174833e-03 9.36524477e-03 1.04058278e-03 + 2.08116556e-03 2.08116556e-03 1.04058278e-03 5.20291366e-03 + 3.12174833e-03 0. 9.36524477e-03 8.32466222e-03 5.20291366e-03 + 3.12174838e-02 9.36524495e-02 8.01248774e-02 4.37044762e-02 + 4.16233111e-03 7.28407968e-03 1.35275759e-02 3.12174833e-03 + 1.24869933e-02 1.04058273e-02 2.08116556e-03 1.04058278e-03 0. + 3.12174833e-03 6.24349667e-03 2.08116556e-03 1.24869933e-02 + 2.80957352e-02 2.28928216e-02 4.16233111e-03 2.08116556e-03 0. 0. + 0. 1.04058278e-03 2.08116556e-03 8.32466222e-03 1.04058278e-03 0. + 1.04058278e-03 8.32466222e-03 1.04058278e-03 2.08116546e-02 + 1.45681594e-02 4.16233111e-03 3.12174833e-03 0. 1.04058278e-03 + 1.04058278e-03 1.04058278e-03 1.04058278e-03 3.12174833e-03 0. 0. + 0. 0. 0. 0. 0. 3.12174833e-03 1.14464108e-02 1.04058278e-03 + 1.04058278e-03 3.12174833e-03 1.04058278e-03 0. 4.16233111e-03 + 1.04058278e-03 3.12174833e-03 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 9.36524477e-03 0. 9.36524477e-03 1.04058273e-02 + 9.36524477e-03 0. 0. 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. + 0. 0. 2.08116556e-03 0. 0. 1.04058278e-03 2.08116556e-03 0. 0. 0. + 0. 0. 0. 0. 3.12174833e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 7.28407968e-03 2.08116556e-03 1.04058278e-03 1.04058278e-03 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 2.08116556e-03 0. + 2.18522381e-02 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 0. + 0. 0. 1.14464108e-02 0. 2.08116556e-03 1.04058278e-03 + 9.36524477e-03 0. 1.24869933e-02 5.20291366e-03 6.24349667e-03 + 8.32466222e-03 0. 2.08116556e-03 2.08116556e-03 2.08116556e-03 0. + 8.32466222e-03 0. 1.04058278e-03 0. 0. 0. 0. 2.08116556e-03 + 1.56087419e-02 2.08116556e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 1.04058278e-03 1.04058278e-03 1.04058278e-03 0. + 1.04058278e-03 8.32466222e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. + 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. 5.20291366e-03 + 8.32466222e-03 1.04058273e-02 0. 8.32466222e-03 0. 2.08116556e-03 + 0. 8.32466222e-03 0. 1.04058278e-03 0. 2.08116556e-03 + 2.08116556e-03 1.04058278e-03 2.08116556e-03 1.14464108e-02 + 5.20291366e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 4.16233111e-03 3.12174833e-03 0. 4.16233111e-03 + 1.14464108e-02 1.14464108e-02 0. 1.24869933e-02 3.12174833e-03 + 2.08116556e-03 1.04058278e-03 1.04058273e-02 1.04058278e-03 + 1.04058278e-03 0. 2.08116556e-03 2.08116556e-03 2.08116556e-03 + 2.08116556e-03 1.97710730e-02 2.70551518e-02 9.36524477e-03 + 3.12174833e-03 6.24349667e-03 1.04058278e-03 0. 3.12174833e-03 + 4.16233111e-03 2.49739867e-02 7.28407968e-03 5.20291366e-03 + 1.35275759e-02 6.24349667e-03 7.28407968e-03 2.70551518e-02 + 1.15504690e-01 2.91363187e-02 1.35275759e-02 2.08116556e-03 + 3.12174833e-03 5.20291366e-03 0. 5.20291366e-03 3.12174833e-03 0. + 0. 0. 0. 5.20291366e-03 0. 3.12174833e-03 4.16233111e-03 + 1.87304895e-02 4.16233111e-03 0. 0. 3.12174833e-03 0. + 1.04058278e-03 1.04058278e-03 4.16233111e-03 0. 0. 0. + 1.87304895e-02 1.04058278e-03 2.91363187e-02 8.32466222e-03 + 2.08116556e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 6.24349667e-03 0. 0. 0. 2.08116556e-03 0. 2.08116556e-03 0. + 3.12174833e-03 0. 0. 1.04058278e-03 1.45681594e-02 0. + 6.24349667e-03 7.28407968e-03 1.56087419e-02 2.08116556e-03 0. 0. + 2.08116556e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 7.28407968e-03 2.08116556e-03 + 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 9.36524477e-03 2.08116556e-03 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 8.32466222e-03 0. 1.04058278e-03 + 2.08116556e-03 7.28407968e-03 0. 5.20291366e-03 5.20291366e-03 0. + 5.20291366e-03 0. 3.12174833e-03 1.04058278e-03 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 0. 3.12174833e-03 3.12174833e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 0. 0. 3.12174833e-03 0. 0. 0. + 0. 3.12174833e-03 0. 1.04058278e-03 7.28407968e-03 6.24349667e-03 + 4.05827276e-02 0. 5.20291403e-02 0. 0. 0. 6.24349667e-03 + 1.04058278e-03 0. 0. 2.08116556e-03 0. 0. 1.04058278e-03 + 5.20291366e-03 1.04058278e-03 3.12174833e-03 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 1.04058278e-03 + 1.14464108e-02 2.39334032e-01 0. 3.32986489e-02 2.08116556e-03 + 2.08116556e-03 0. 1.35275759e-02 0. 0. 0. 2.08116556e-03 + 2.08116556e-03 1.04058278e-03 1.04058278e-03 1.35275759e-02 + 1.56087419e-02 5.51508889e-02 0. 1.56087419e-02 0. 3.12174833e-03 + 0. 1.66493244e-02 6.24349667e-03 7.28407968e-03 0. 1.66493244e-02 + 1.04058273e-02 7.28407968e-03 1.14464108e-02 5.93132190e-02 + 3.12174833e-03 1.35275759e-02 0. 3.12174833e-03 6.24349667e-03 + 2.08116556e-03 1.04058278e-03 2.70551518e-02 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.24869933e-02 1.14464108e-02 3.12174833e-03 + 0. 0. 2.08116556e-03 0. 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. + 1.14464108e-02 2.08116556e-03 5.20291366e-03 4.57856432e-02 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 2.08116556e-03 0. 0. 0. 0. 0. 2.08116556e-03 1.04058278e-03 0. 0. + 0. 3.12174833e-03 0. 0. 5.20291366e-03 7.28407968e-03 0. 0. 0. + 6.24349667e-03 0. 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. + 4.16233111e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. + 0. 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 3.43392305e-02 3.12174833e-03 1.04058278e-03 1.04058278e-03 + 3.12174833e-03 0. 0. 1.04058278e-03 1.35275759e-02 2.08116556e-03 + 0. 0. 1.04058273e-02 0. 6.24349667e-03 7.28407968e-03 0. + 5.20291366e-03 0. 0. 0. 0. 0. 1.97710730e-02 0. 0. 0. 0. 0. 0. 0. + 1.14464108e-02 0. 2.08116556e-03 0. 0. 0. 0. 0. 1.04058278e-03 0. + 0. 0. 0. 1.04058278e-03 2.08116556e-03 0. 1.04058273e-02 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. + 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 2.08116556e-03 + 3.12174833e-03 3.85015644e-02 0. 1.04058278e-03 0. 1.04058278e-03 + 0. 3.01769003e-02 0. 0. 0. 0. 0. 0. 0. 9.36524477e-03 + 1.04058278e-03 4.16233111e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. + 8.32466222e-03 2.08116556e-03 1.56087419e-02 0. 2.08116556e-03 0. + 1.04058278e-03 0. 1.14464108e-02 0. 0. 0. 0. 0. 0. 0. + 8.32466222e-03 1.29032269e-01 1.52965665e-01 0. 1.04058273e-02 + 3.12174833e-03 0. 1.04058278e-03 2.18522381e-02 3.53798158e-02 + 2.28928216e-02 0. 3.12174833e-03 1.45681594e-02 1.35275759e-02 + 4.16233111e-03 1.09261192e-01 1.76899079e-02 1.04058273e-02 0. + 1.04058278e-03 0. 2.08116556e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 2.91363187e-02 1.87304895e-02 + 1.04058278e-03 0. 0. 2.08116556e-03 0. 2.08116556e-03 0. 0. 0. 0. + 0. 0. 0. 7.28407968e-03 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 3.12174833e-03 2.08116556e-03 0. + 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. + 3.12174833e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 4.16233111e-03 3.12174833e-03 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 6.55567124e-02 2.08116556e-03 0. 0. 0. 0. 0. 0. + 4.16233111e-03 0. 0. 0. 0. 0. 1.04058278e-03 1.04058278e-03 + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 1.04058278e-03 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 2.08116556e-03 0. 0. + 0. 0. 0. 0. 0. 0. 2.08116556e-03 0. 0. 0. 1.04058278e-03 + 1.04058278e-03 6.24349667e-03 9.36524477e-03 2.18522381e-02 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. 0. 0. + 1.04058278e-03 1.04058278e-03 1.35275759e-02 3.96462053e-01 + 1.67533830e-01 1.04058278e-03 1.04058278e-03 2.08116556e-03 + 4.16233111e-03 1.04058278e-03 2.08116556e-03 6.03538007e-02 + 3.01769003e-02 0. 0. 1.24869933e-02 1.76899079e-02 8.32466222e-03 + 2.39334032e-02 1.56087419e-02 1.87304895e-02 0. 6.24349667e-03 + 7.28407968e-03 2.08116556e-03 1.04058273e-02 3.22580673e-02 0. 0. + 0. 0. 3.12174833e-03 0. 9.36524477e-03 4.68262248e-02 + 1.66493244e-02 4.16233111e-03 0. 1.04058278e-03 0. 0. 0. + 1.04058278e-03 2.08116556e-03 2.08116556e-03 0. 0. 2.60145701e-02 + 1.04058278e-03 2.28928216e-02 3.43392305e-02 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 4.16233111e-03 0. 0. 0. 0. 0. 0. 0. + 1.04058273e-02 0. 0. 1.04058278e-03 1.14464108e-02 0. + 1.35275759e-02 1.04058273e-02 6.24349667e-03 1.04058278e-03 0. 0. + 3.12174833e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 2.08116556e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. + 0. 0. 6.24349667e-03 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 1.04058278e-03 2.39334032e-02 1.04058278e-03 + 2.08116556e-03 0. 0. 0. 0. 1.04058278e-03 9.26118642e-02 + 1.04058278e-03 1.04058278e-03 0. 1.87304895e-02 0. 1.45681594e-02 + 9.36524477e-03 1.04058278e-03 6.24349667e-03 0. 1.04058273e-02 0. + 0. 0. 6.24349676e-02 0. 0. 0. 0. 0. 0. 0. 3.01769003e-02 + 1.04058278e-03 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. + 1.04058278e-03 0. 1.04058278e-03 0. 1.04058278e-03 2.08116556e-03 + 0. 1.04058278e-03 1.76899079e-02 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 1.04058278e-03 0. 8.32466222e-03 2.08116556e-03 + 1.97710730e-02 0. 1.97710730e-02 0. 0. 1.04058278e-03 + 2.28928216e-02 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. + 8.32466222e-03 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 1.04058278e-03 6.24349667e-03 + 1.04058273e-02 4.99479733e-02 0. 7.28407968e-03 0. 0. + 1.04058278e-03 1.35275759e-02 0. 1.04058278e-03 0. 0. + 1.04058278e-03 1.04058278e-03 2.08116556e-03 1.76899079e-02 + 3.43392305e-02 1.97710730e-02 0. 8.32466222e-03 0. 0. 0. + 6.24349667e-03 1.24869933e-02 4.16233111e-03 2.08116556e-03 + 1.04058278e-03 0. 2.08116556e-03 1.04058273e-02 5.72320521e-02 + 2.39334032e-02 1.45681594e-02 2.08116556e-03 1.14464108e-02 + 6.24349667e-03 0. 1.14464108e-02 4.16233111e-03 1.04058278e-03 + 1.04058278e-03 0. 0. 3.12174833e-03 0. 9.36524477e-03 + 1.45681594e-02 2.08116546e-02 5.20291366e-03 3.12174833e-03 + 1.04058278e-03 4.16233111e-03 0. 1.04058278e-03 2.08116556e-03 + 1.04058278e-03 1.04058278e-03 0. 0. 5.93132190e-02 1.04058278e-03 + 1.97710723e-01 2.18522381e-02 5.20291366e-03 1.04058278e-03 0. + 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 + 6.24349667e-03 0. 0. 1.04058278e-03 2.08116556e-03 0. + 1.04058278e-03 0. 2.08116556e-03 0. 0. 1.04058278e-03 + 2.70551518e-02 0. 5.20291403e-02 4.16233111e-03 2.08116556e-03 + 4.16233111e-03 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 1.04058278e-03 1.04058278e-03 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 1.04058278e-03 0. + 4.16233111e-03 6.24349667e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 4.16233111e-03 3.12174833e-03 0. 0. 0. 0. 0. 0. + 6.24349667e-03 1.04058278e-03 0. 0. 6.24349667e-03 0. + 7.28407968e-03 3.12174833e-03 0. 2.08116556e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 1.04058278e-03 0. 5.20291366e-03 0. 0. 0. + 1.04058278e-03 0. 0. 0. 1.04058278e-03 0. 0. 0. 1.04058278e-03 + 2.08116556e-03 0. 1.04058278e-03 5.20291366e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.04058278e-03 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 6.24349667e-03 0. 3.32986489e-02 0. + 1.97710730e-02 0. 0. 0. 9.36524477e-03 0. 0. 0. 0. 1.04058278e-03 + 2.08116556e-03 0. 6.24349667e-03 1.04058278e-03 0. 0. 0. 0. 0. + 1.04058278e-03 0. 0. 0. 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 2.08116556e-03 1.04058273e-02 1.36316344e-01 0. 2.08116546e-02 0. + 0. 0. 2.08116556e-03 0. 1.04058278e-03 0. 0. 1.04058278e-03 + 3.12174833e-03 0. 9.36524477e-03 3.12174833e-03 2.08116546e-02 0. + 1.04058278e-03 0. 0. 0. 2.08116556e-03 8.32466222e-03 + 1.14464108e-02 0. 3.12174833e-03 1.45681594e-02 6.24349667e-03 + 1.66493244e-02 3.95421460e-02
+ + 2 + 1 +
i
+ + 1 2
+
diff --git a/test/runner.rb b/test/runner.rb new file mode 100755 index 00000000..1473b55e --- /dev/null +++ b/test/runner.rb @@ -0,0 +1,30 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' + +src_testdir = File.dirname(File.expand_path(__FILE__)) +if Test::Unit.methods.include? :setup_argv + srcdir = File.dirname(src_testdir) + Test::Unit.setup_argv {|files| + if files.empty? + [src_testdir] + else + files.map {|f| + if File.exist? "#{src_testdir}/#{f}" + "#{src_testdir}/#{f}" + elsif File.exist? "#{srcdir}/#{f}" + "#{srcdir}/#{f}" + elsif File.exist? f + f + else + raise ArgumentError, "not found: #{f}" + end + } + end + } +elsif Test::Unit.constants.map {|c| c.to_sym }.include? :AutoRunner + Test::Unit::AutoRunner.run(true, src_testdir) +else + raise 'Test runner not found' +end + diff --git a/test/samples/airplane.jpg b/test/samples/airplane.jpg new file mode 100644 index 00000000..a9b46526 Binary files /dev/null and b/test/samples/airplane.jpg differ diff --git a/test/samples/baboon.jpg b/test/samples/baboon.jpg new file mode 100644 index 00000000..2f98d835 Binary files /dev/null and b/test/samples/baboon.jpg differ diff --git a/test/samples/baboon200.jpg b/test/samples/baboon200.jpg new file mode 100644 index 00000000..1b873e0c Binary files /dev/null and b/test/samples/baboon200.jpg differ diff --git a/test/samples/baboon200_rotated.jpg b/test/samples/baboon200_rotated.jpg new file mode 100644 index 00000000..86160db9 Binary files /dev/null and b/test/samples/baboon200_rotated.jpg differ diff --git a/test/samples/blank0.jpg b/test/samples/blank0.jpg new file mode 100644 index 00000000..878fb3b3 Binary files /dev/null and b/test/samples/blank0.jpg differ diff --git a/test/samples/blank1.jpg b/test/samples/blank1.jpg new file mode 100644 index 00000000..b151a5c6 Binary files /dev/null and b/test/samples/blank1.jpg differ diff --git a/test/samples/blank2.jpg b/test/samples/blank2.jpg new file mode 100644 index 00000000..37dde3cd Binary files /dev/null and b/test/samples/blank2.jpg differ diff --git a/test/samples/blank3.jpg b/test/samples/blank3.jpg new file mode 100644 index 00000000..445c93e7 Binary files /dev/null and b/test/samples/blank3.jpg differ diff --git a/test/samples/blank4.jpg b/test/samples/blank4.jpg new file mode 100644 index 00000000..7f3214ba Binary files /dev/null and b/test/samples/blank4.jpg differ diff --git a/test/samples/blank5.jpg b/test/samples/blank5.jpg new file mode 100644 index 00000000..36ad8704 Binary files /dev/null and b/test/samples/blank5.jpg differ diff --git a/test/samples/blank6.jpg b/test/samples/blank6.jpg new file mode 100644 index 00000000..1500513f Binary files /dev/null and b/test/samples/blank6.jpg differ diff --git a/test/samples/blank7.jpg b/test/samples/blank7.jpg new file mode 100644 index 00000000..0a1813f7 Binary files /dev/null and b/test/samples/blank7.jpg differ diff --git a/test/samples/blank8.jpg b/test/samples/blank8.jpg new file mode 100644 index 00000000..d352c0a6 Binary files /dev/null and b/test/samples/blank8.jpg differ diff --git a/test/samples/blank9.jpg b/test/samples/blank9.jpg new file mode 100644 index 00000000..7bb62bf9 Binary files /dev/null and b/test/samples/blank9.jpg differ diff --git a/test/samples/cat.jpg b/test/samples/cat.jpg new file mode 100644 index 00000000..df4a907e Binary files /dev/null and b/test/samples/cat.jpg differ diff --git a/test/samples/chessboard.jpg b/test/samples/chessboard.jpg new file mode 100644 index 00000000..53ca1dd5 Binary files /dev/null and b/test/samples/chessboard.jpg differ diff --git a/test/samples/contours.jpg b/test/samples/contours.jpg new file mode 100644 index 00000000..9e730176 Binary files /dev/null and b/test/samples/contours.jpg differ diff --git a/test/samples/fruits.jpg b/test/samples/fruits.jpg new file mode 100644 index 00000000..a89b84a5 Binary files /dev/null and b/test/samples/fruits.jpg differ diff --git a/test/samples/haarcascade_frontalface_alt.xml.gz b/test/samples/haarcascade_frontalface_alt.xml.gz new file mode 100644 index 00000000..cfc54a85 Binary files /dev/null and b/test/samples/haarcascade_frontalface_alt.xml.gz differ diff --git a/test/samples/inpaint-mask.bmp b/test/samples/inpaint-mask.bmp new file mode 100644 index 00000000..7954eb2c Binary files /dev/null and b/test/samples/inpaint-mask.bmp differ diff --git a/test/samples/lena-256x256.jpg b/test/samples/lena-256x256.jpg new file mode 100644 index 00000000..349f8e9d Binary files /dev/null and b/test/samples/lena-256x256.jpg differ diff --git a/test/samples/lena-32x32.jpg b/test/samples/lena-32x32.jpg new file mode 100644 index 00000000..3dffa0c8 Binary files /dev/null and b/test/samples/lena-32x32.jpg differ diff --git a/test/samples/lena-eyes.jpg b/test/samples/lena-eyes.jpg new file mode 100644 index 00000000..e3f2caa7 Binary files /dev/null and b/test/samples/lena-eyes.jpg differ diff --git a/test/samples/lena-inpaint.jpg b/test/samples/lena-inpaint.jpg new file mode 100644 index 00000000..05d0c995 Binary files /dev/null and b/test/samples/lena-inpaint.jpg differ diff --git a/test/samples/lena.jpg b/test/samples/lena.jpg new file mode 100644 index 00000000..f06aa74a Binary files /dev/null and b/test/samples/lena.jpg differ diff --git a/test/samples/lines.jpg b/test/samples/lines.jpg new file mode 100644 index 00000000..cbe8fcd2 Binary files /dev/null and b/test/samples/lines.jpg differ diff --git a/test/samples/messy0.jpg b/test/samples/messy0.jpg new file mode 100644 index 00000000..918e943f Binary files /dev/null and b/test/samples/messy0.jpg differ diff --git a/test/samples/messy1.jpg b/test/samples/messy1.jpg new file mode 100644 index 00000000..7405cf58 Binary files /dev/null and b/test/samples/messy1.jpg differ diff --git a/test/samples/movie_sample.avi b/test/samples/movie_sample.avi new file mode 100644 index 00000000..72ee2b35 Binary files /dev/null and b/test/samples/movie_sample.avi differ diff --git a/test/samples/one_way_train_0000.jpg b/test/samples/one_way_train_0000.jpg new file mode 100644 index 00000000..457820e9 Binary files /dev/null and b/test/samples/one_way_train_0000.jpg differ diff --git a/test/samples/one_way_train_0001.jpg b/test/samples/one_way_train_0001.jpg new file mode 100644 index 00000000..7f3990f4 Binary files /dev/null and b/test/samples/one_way_train_0001.jpg differ diff --git a/test/samples/partially_blank0.jpg b/test/samples/partially_blank0.jpg new file mode 100644 index 00000000..54c5b489 Binary files /dev/null and b/test/samples/partially_blank0.jpg differ diff --git a/test/samples/partially_blank1.jpg b/test/samples/partially_blank1.jpg new file mode 100644 index 00000000..2ab27b43 Binary files /dev/null and b/test/samples/partially_blank1.jpg differ diff --git a/test/samples/smooth0.jpg b/test/samples/smooth0.jpg new file mode 100644 index 00000000..7b9fbb0a Binary files /dev/null and b/test/samples/smooth0.jpg differ diff --git a/test/samples/smooth1.jpg b/test/samples/smooth1.jpg new file mode 100644 index 00000000..ff2d09b9 Binary files /dev/null and b/test/samples/smooth1.jpg differ diff --git a/test/samples/smooth2.jpg b/test/samples/smooth2.jpg new file mode 100644 index 00000000..090958ed Binary files /dev/null and b/test/samples/smooth2.jpg differ diff --git a/test/samples/smooth3.jpg b/test/samples/smooth3.jpg new file mode 100644 index 00000000..240c5d53 Binary files /dev/null and b/test/samples/smooth3.jpg differ diff --git a/test/samples/smooth4.jpg b/test/samples/smooth4.jpg new file mode 100644 index 00000000..2a3fd16f Binary files /dev/null and b/test/samples/smooth4.jpg differ diff --git a/test/samples/smooth5.jpg b/test/samples/smooth5.jpg new file mode 100644 index 00000000..cecdb41d Binary files /dev/null and b/test/samples/smooth5.jpg differ diff --git a/test/samples/smooth6.jpg b/test/samples/smooth6.jpg new file mode 100644 index 00000000..d4448e24 Binary files /dev/null and b/test/samples/smooth6.jpg differ diff --git a/test/samples/str-cv-rotated.jpg b/test/samples/str-cv-rotated.jpg new file mode 100644 index 00000000..e2ca43e4 Binary files /dev/null and b/test/samples/str-cv-rotated.jpg differ diff --git a/test/samples/str-cv.jpg b/test/samples/str-cv.jpg new file mode 100644 index 00000000..b0b0abf7 Binary files /dev/null and b/test/samples/str-cv.jpg differ diff --git a/test/samples/str-ov.jpg b/test/samples/str-ov.jpg new file mode 100644 index 00000000..508ac11f Binary files /dev/null and b/test/samples/str-ov.jpg differ diff --git a/test/samples/stuff.jpg b/test/samples/stuff.jpg new file mode 100644 index 00000000..720d3413 Binary files /dev/null and b/test/samples/stuff.jpg differ diff --git a/test/test_curve.rb b/test/test_curve.rb new file mode 100755 index 00000000..9e8430c5 --- /dev/null +++ b/test/test_curve.rb @@ -0,0 +1,43 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::Curve +class TestCurve < OpenCVTestCase + def setup + @contour1 = CvContour.new + + mat0 = create_cvmat(128, 128, :cv8u, 1) { |j, i| + (j - 64) ** 2 + (i - 64) ** 2 <= (32 ** 2) ? CvColor::White : CvColor::Black + } + @contour2 = mat0.find_contours + end + + def test_closed + assert_false(@contour1.closed?) + assert(@contour2.closed?) + end + + def test_convex + assert_false(@contour1.convex?) + end + + def test_hole + assert_false(@contour1.hole?) + end + + def test_simple + assert(@contour1.simple?) + end + + def test_arc_length + assert_in_delta(211.480, @contour2.arc_length, 0.001) + assert_in_delta(32.181, @contour2.arc_length(CvSlice.new(0, 9), true), 0.001) + assert_in_delta(32.181, @contour2.arc_length(0..10, true), 0.001) + end +end + diff --git a/test/test_cvavgcomp.rb b/test/test_cvavgcomp.rb new file mode 100755 index 00000000..6ba543cd --- /dev/null +++ b/test/test_cvavgcomp.rb @@ -0,0 +1,24 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvAvgComp +class TestCvAvgComp < OpenCVTestCase + def setup + @avgcomp = CvAvgComp.new + end + + def test_initialize + assert_equal(CvAvgComp, @avgcomp.class) + assert(@avgcomp.is_a? CvRect) + end + + def test_neighbors + assert_kind_of(Integer, @avgcomp.neighbors) + end +end + diff --git a/test/test_cvbox2d.rb b/test/test_cvbox2d.rb new file mode 100755 index 00000000..ced01d74 --- /dev/null +++ b/test/test_cvbox2d.rb @@ -0,0 +1,76 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvBox2D +class TestCvBox2D < OpenCVTestCase + class MyPoint; end + def test_initialize + box = CvBox2D.new + assert_in_delta(0, box.center.x, 0.001) + assert_in_delta(0, box.center.y, 0.001) + assert_in_delta(0, box.size.width, 0.001) + assert_in_delta(0, box.size.height, 0.001) + assert_in_delta(0, box.angle, 0.001) + + box = CvBox2D.new(CvPoint2D32f.new(1.1, 2.2), CvSize2D32f.new(3.3, 4.4), 5.5) + assert_in_delta(1.1, box.center.x, 0.001) + assert_in_delta(2.2, box.center.y, 0.001) + assert_in_delta(3.3, box.size.width, 0.001) + assert_in_delta(4.4, box.size.height, 0.001) + assert_in_delta(5.5, box.angle, 0.001) + end + + def test_center + box = CvBox2D.new + box.center = CvPoint2D32f.new(1.1, 2.2) + assert_in_delta(1.1, box.center.x, 0.001) + assert_in_delta(2.2, box.center.y, 0.001) + + box.center.x = 3.3 + box.center.y = 4.4 + assert_in_delta(3.3, box.center.x, 0.001) + assert_in_delta(4.4, box.center.y, 0.001) + end + + def test_size + box = CvBox2D.new + box.size = CvSize2D32f.new(1.1, 2.2) + assert_in_delta(1.1, box.size.width, 0.001) + assert_in_delta(2.2, box.size.height, 0.001) + + box.size.width = 3.3 + box.size.height = 4.4 + assert_in_delta(3.3, box.size.width, 0.001) + assert_in_delta(4.4, box.size.height, 0.001) + end + + def test_angle + box = CvBox2D.new + box.angle = 1.1 + assert_in_delta(1.1, box.angle, 0.001) + end + + def test_points + box = CvBox2D.new + box.center = CvPoint2D32f.new(10, 20) + box.size = CvSize2D32f.new(5, 7) + pt = box.points + + assert_equal(4, pt.size) + assert_in_delta(7.5, pt[0].x, 0.001) + assert_in_delta(23.5, pt[0].y, 0.001) + assert_in_delta(7.5, pt[1].x, 0.001) + assert_in_delta(16.5, pt[1].y, 0.001) + assert_in_delta(12.5, pt[2].x, 0.001) + assert_in_delta(16.5, pt[2].y, 0.001) + assert_in_delta(12.5, pt[3].x, 0.001) + assert_in_delta(23.5, pt[3].y, 0.001) + end +end + + diff --git a/test/test_cvcapture.rb b/test/test_cvcapture.rb new file mode 100755 index 00000000..5dd894f2 --- /dev/null +++ b/test/test_cvcapture.rb @@ -0,0 +1,191 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvCapture +class TestCvCapture < OpenCVTestCase + def setup + @cap = CvCapture.open(AVI_SAMPLE) + @cap.query + end + + def teardown + @cap = nil + end + + def test_INTERFACE + assert_equal(CvCapture::INTERFACE[:any], 0) + assert_equal(CvCapture::INTERFACE[:mil], 100) + assert_equal(CvCapture::INTERFACE[:vfw], 200) + assert_equal(CvCapture::INTERFACE[:v4l], 200) + assert_equal(CvCapture::INTERFACE[:v4l2], 200) + assert_equal(CvCapture::INTERFACE[:fireware], 300) + assert_equal(CvCapture::INTERFACE[:ieee1394], 300) + assert_equal(CvCapture::INTERFACE[:dc1394], 300) + assert_equal(CvCapture::INTERFACE[:cmu1394], 300) + assert_equal(CvCapture::INTERFACE[:stereo], 400) + assert_equal(CvCapture::INTERFACE[:tyzx], 400) + assert_equal(CvCapture::INTERFACE[:tyzx_left], 400) + assert_equal(CvCapture::INTERFACE[:tyzx_right], 401) + assert_equal(CvCapture::INTERFACE[:tyzx_color], 402) + assert_equal(CvCapture::INTERFACE[:tyzx_z], 403) + assert_equal(CvCapture::INTERFACE[:qt], 500) + assert_equal(CvCapture::INTERFACE[:quicktime], 500) + end + + def test_open + cap1 = CvCapture.open(AVI_SAMPLE) + assert_equal(CvCapture, cap1.class) + + # Uncomment the following lines to test capturing from camera + # cap2 = CvCapture.open(0) + # assert_equal(CvCapture, cap2.class) + # CvCapture::INTERFACE.each { |k, v| + # cap3 = CvCapture.open(k) + # assert_equal(CvCapture, cap3.class) + # } + end + + def test_close + cap1 = CvCapture.open(AVI_SAMPLE) + cap1.close + assert_raise(IOError) do + cap1.query + end + end + + def test_grab + assert(@cap.grab) + end + + def test_retrieve + @cap.grab + img = @cap.retrieve + assert_equal(IplImage, img.class) + end + + def test_query + img = @cap.query + assert_equal(IplImage, img.class) + end + + def test_millisecond + @cap.millisecond = 10 + assert(@cap.millisecond.is_a? Numeric) + # assert_equal(10, @cap.millisecond) + @cap.millisecond = 20 + assert(@cap.millisecond.is_a? Numeric) + # assert_equal(20, @cap.millisecond) + end + + def test_frames + @cap.frames = 10 + assert(@cap.frames.is_a? Numeric) + # assert_equal(10, @cap.frames) + @cap.frames = 20 + assert(@cap.frames.is_a? Numeric) + # assert_equal(20, @cap.frames) + end + + def test_avi_ratio + @cap.avi_ratio = 0.1 + assert(@cap.avi_ratio.is_a? Numeric) + # assert_equal(0.1, @cap.avi_ratio) + @cap.avi_ratio = 0.8 + assert(@cap.avi_ratio.is_a? Numeric) + # assert_equal(0.8, @cap.avi_ratio) + end + + def test_size + @cap.size = CvSize.new(320, 240) + assert_equal(CvSize, @cap.size.class) + # assert_equal(320, @cap.size.width) + # assert_equal(240, @cap.size.height) + + @cap.size = CvSize.new(640, 480) + assert_equal(CvSize, @cap.size.class) + # assert_equal(640, @cap.size.width) + # assert_equal(480, @cap.size.height) + end + + def test_width + @cap.width = 320 + assert(@cap.width.is_a? Numeric) + # assert_equal(320, @cap.width) + @cap.width = 640 + assert(@cap.width.is_a? Numeric) + # assert_equal(640, @cap.width) + end + + def test_height + @cap.height = 240 + assert(@cap.height.is_a? Numeric) + # assert_equal(240, @cap.height) + @cap.height = 480 + assert(@cap.height.is_a? Numeric) + # assert_equal(480, @cap.height) + end + + def test_fps + @cap.fps = 15 + assert(@cap.fps.is_a? Numeric) + # assert_equal(15, @cap.fps) + @cap.fps = 30 + assert(@cap.fps.is_a? Numeric) + # assert_equal(30, @cap.fps) + end + + def test_fourcc + assert_equal(String, @cap.fourcc.class) + end + + def test_frame_count + assert(@cap.frame_count.is_a? Numeric) + end + + def test_format + assert(@cap.format.is_a? Numeric) + end + + def test_mode + assert(@cap.mode.is_a? Numeric) + end + + def test_brightness + assert(@cap.brightness.is_a? Numeric) + end + + def test_contrast + assert(@cap.contrast.is_a? Numeric) + end + + def test_saturation + assert(@cap.saturation.is_a? Numeric) + end + + def test_hue + assert(@cap.hue.is_a? Numeric) + end + + def test_gain + assert(@cap.gain.is_a? Numeric) + end + + def test_exposure + assert(@cap.exposure.is_a? Numeric) + end + + def test_convert_rgb + assert((@cap.convert_rgb == true) || + (@cap.convert_rgb == false)) + end + + def test_rectification + assert(@cap.rectification.is_a? Numeric) + end +end + diff --git a/test/test_cvchain.rb b/test/test_cvchain.rb new file mode 100755 index 00000000..a1f83bb7 --- /dev/null +++ b/test/test_cvchain.rb @@ -0,0 +1,108 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvChain +class TestCvChain < OpenCVTestCase + def test_APPROX_OPTION + assert_equal(:approx_simple, CvChain::APPROX_CHAIN_OPTION[:method]) + assert_equal(0, CvChain::APPROX_CHAIN_OPTION[:parameter]) + assert_equal(0, CvChain::APPROX_CHAIN_OPTION[:minimal_perimeter]) + assert_false(CvChain::APPROX_CHAIN_OPTION[:recursive]) + end + + def test_initialize + chain = CvChain.new + assert_not_nil(chain) + assert_equal(CvChain, chain.class) + assert(chain.is_a? CvSeq) + end + + def test_origin + mat0 = create_cvmat(128, 128, :cv8u, 1) { |j, i| + (j - 64) ** 2 + (i - 64) ** 2 <= (32 ** 2) ? CvColor::White : CvColor::Black + } + chain = mat0.find_contours(:mode => CV_RETR_EXTERNAL, :method => CV_CHAIN_CODE) + assert_equal(CvChain, chain.class) + assert_equal(64, chain.origin.x) + assert_equal(32, chain.origin.y) + + chain.origin = CvPoint.new(32, 64) + assert_equal(32, chain.origin.x) + assert_equal(64, chain.origin.y) + end + + def test_codes + mat0 = create_cvmat(128, 128, :cv8u, 1) { |j, i| + (j - 64) ** 2 + (i - 64) ** 2 <= (32 ** 2) ? CvColor::White : CvColor::Black + } + chain = mat0.find_contours(:mode => CV_RETR_EXTERNAL, :method => CV_CHAIN_CODE) + assert_equal(Array, chain.codes.class) + assert(chain.codes.all? { |a| (Integer === a) and (a >= 0 and a <= 7) }) + end + + def test_points + mat0 = create_cvmat(128, 128, :cv8u, 1) { |j, i| + (j - 64) ** 2 + (i - 64) ** 2 <= (32 ** 2) ? CvColor::White : CvColor::Black + } + chain = mat0.find_contours(:mode => CV_RETR_EXTERNAL, :method => CV_CHAIN_CODE) + assert_equal(Array, chain.points.class) + assert(chain.points.all? { |a| a.class == CvPoint }) + end + + def test_approx_chains + mat0 = create_cvmat(128, 128, :cv8u, 1) { |j, i| + (j - 64) ** 2 + (i - 64) ** 2 <= (32 ** 2) ? CvColor::White : CvColor::Black + } + chain = mat0.find_contours(:mode => CV_RETR_EXTERNAL, :method => CV_CHAIN_CODE) + + contours = chain.approx_chains + assert_equal(CvChain, contours.class) + assert(contours.size > 0) + assert(contours.all? { |c| c.class == CvPoint }) + + [CV_CHAIN_APPROX_NONE, CV_CHAIN_APPROX_SIMPLE, + CV_CHAIN_APPROX_TC89_L1, CV_CHAIN_APPROX_TC89_KCOS, + :approx_none, :approx_simple, :approx_tc89_l1, :approx_tc89_kcos].each { |method| + contours = chain.approx_chains(:method => method) + assert_equal(CvChain, contours.class) + assert(contours.size > 0) + assert(contours.all? { |c| c.class == CvPoint }) + } + + contours = chain.approx_chains(:minimal_parameter => 10) + assert_equal(CvChain, contours.class) + assert(contours.size > 0) + assert(contours.all? { |c| c.class == CvPoint }) + + contours = chain.approx_chains(:minimal_perimeter => (32 * 2 * Math::PI).ceil) + assert_nil(contours) + + [true, false].each { |recursive| + contours = chain.approx_chains(:recursive => recursive) + assert_equal(CvChain, contours.class) + assert(contours.size > 0) + assert(contours.all? { |c| c.class == CvPoint }) + } + + contours = chain.approx_chains(:method => :approx_simple, + :minimal_parameter => 100, :recursive => false) + assert_equal(CvChain, contours.class) + assert(contours.size > 0) + assert(contours.all? { |c| c.class == CvPoint }) + + # Uncomment the following lines to show the result + # contours = chain.approx_chains + # dst = mat0.clone.zero + # begin + # dst.draw_contours!(contours, CvColor::White, CvColor::Black, 2, + # :thickness => 1, :line_type => :aa) + # end while (contours = contours.h_next) + # snap dst + end +end + diff --git a/test/test_cvcircle32f.rb b/test/test_cvcircle32f.rb new file mode 100755 index 00000000..83319397 --- /dev/null +++ b/test/test_cvcircle32f.rb @@ -0,0 +1,41 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvCircle32f +class TestCvCircle32f < OpenCVTestCase + def setup + @circle = CvCircle32f.new + end + + def test_initialize + assert_equal(CvCircle32f, @circle.class) + end + + def test_center + assert_equal(CvPoint2D32f, @circle.center.class) + end + + def test_radius + assert_equal(Float, @circle.radius.class) + end + + def test_aref + assert_equal(Float, @circle[0].class) + assert_equal(Float, @circle[1].class) + assert_equal(Float, @circle[2].class) + assert_raise(IndexError) { + @circle[3] + } + end + + def test_to_ary + assert_equal(Array, @circle.to_ary.class) + assert_equal(2, @circle.to_ary.size) + end +end + diff --git a/test/test_cvconnectedcomp.rb b/test/test_cvconnectedcomp.rb new file mode 100755 index 00000000..4105c402 --- /dev/null +++ b/test/test_cvconnectedcomp.rb @@ -0,0 +1,61 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvConnectedComp +class TestCvConnectedComp < OpenCVTestCase + def setup + @connected_comp = CvConnectedComp.new(9216, CvScalar.new(1, 2, 3, 4), + CvRect.new(1, 2, 3, 4), CvSeq.new(CV_SEQ_ELTYPE_INDEX)) + end + + def test_initialize + connected_comp = CvConnectedComp.new + assert_equal(CvConnectedComp, connected_comp.class) + assert_not_nil(connected_comp.area) + assert_not_nil(connected_comp.value) + assert_not_nil(connected_comp.rect) + assert_not_nil(connected_comp.contour) + + connected_comp = CvConnectedComp.new(100, CvScalar.new(1, 2, 3, 4), + CvRect.new(1, 2, 3, 4), CvSeq.new(CV_SEQ_ELTYPE_POINT)) + assert_equal(CvConnectedComp, connected_comp.class) + assert_not_nil(connected_comp.area) + assert_not_nil(connected_comp.value) + assert_not_nil(connected_comp.rect) + assert_not_nil(connected_comp.contour) + end + + def test_area + assert_in_delta(9216.0, @connected_comp.area, 0.01) + end + + def test_value + assert_equal(CvScalar, @connected_comp.value.class) + assert_cvscalar_equal(CvScalar.new(1, 2, 3, 4), @connected_comp.value) + end + + def test_rect + assert_equal(CvRect, @connected_comp.rect.class) + assert_equal(1, @connected_comp.rect.x) + assert_equal(2, @connected_comp.rect.y) + assert_equal(3, @connected_comp.rect.width) + assert_equal(4, @connected_comp.rect.height) + + @connected_comp.rect = CvRect.new(10, 20, 30, 40); + assert_equal(10, @connected_comp.rect.x) + assert_equal(20, @connected_comp.rect.y) + assert_equal(30, @connected_comp.rect.width) + assert_equal(40, @connected_comp.rect.height) + end + + def test_contour + assert_equal(CvContour, @connected_comp.contour.class) + assert_not_nil(@connected_comp.contour) + end +end + diff --git a/test/test_cvcontour.rb b/test/test_cvcontour.rb new file mode 100755 index 00000000..398011e3 --- /dev/null +++ b/test/test_cvcontour.rb @@ -0,0 +1,171 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvContour +class TestCvContour < OpenCVTestCase + def test_APPROX_OPTION + assert_equal(0, CvContour::APPROX_OPTION[:method]) + assert_equal(1.0, CvContour::APPROX_OPTION[:accuracy]) + assert_false(CvContour::APPROX_OPTION[:recursive]) + end + + def test_initialize + contour = CvContour.new + assert_not_nil(contour) + assert_equal(CvContour, contour.class) + assert(contour.is_a? CvSeq) + end + + def test_rect + contour = CvContour.new + assert_not_nil(contour.rect) + assert_equal(CvRect, contour.rect.class) + end + + def test_color + contour = CvContour.new + assert_equal(0, contour.color) + contour.color = 1 + assert_equal(1, contour.color) + end + + def test_reserved + reserved = CvContour.new.reserved + assert_equal(Array, reserved.class) + assert_equal(3, reserved.size) + end + + def test_approx_poly + mat0 = create_cvmat(128, 128, :cv8u, 1) { |j, i| + (j - 64) ** 2 + (i - 64) ** 2 <= (32 ** 2) ? CvColor::White : CvColor::Black + } + contours = mat0.find_contours(:mode => CV_RETR_EXTERNAL) + + poly = contours.approx_poly + assert_equal(CvContour, poly.class) + assert(poly.size > 0) + assert(poly.all? { |c| c.class == CvPoint }) + + poly = contours.approx_poly(:method => :dp) + assert_equal(CvContour, poly.class) + assert(poly.size > 0) + assert(poly.all? { |c| c.class == CvPoint }) + + poly = contours.approx_poly(:accuracy => 2.0) + assert_equal(CvContour, poly.class) + assert(poly.size > 0) + assert(poly.all? { |c| c.class == CvPoint }) + + [true, false, 1, 0].each { |recursive| + poly = contours.approx_poly(:recursive => recursive) + assert_equal(CvContour, poly.class) + assert(poly.size > 0) + assert(poly.all? { |c| c.class == CvPoint }) + } + + poly = contours.approx_poly(:method => :dp, :accuracy => 2.0, :recursive => false) + assert_equal(CvContour, poly.class) + assert(poly.size > 0) + assert(poly.all? { |c| c.class == CvPoint }) + + # Uncomment the following lines to show the result + # poly = contours.approx_poly(:accuracy => 3.0) + # dst = mat0.clone.zero + # begin + # dst.draw_contours!(poly, CvColor::White, CvColor::Black, 2, + # :thickness => 1, :line_type => :aa) + # end while (poly = poly.h_next) + # snap dst + end + + def test_bounding_rect + mat0 = create_cvmat(128, 128, :cv8u, 1) { |j, i| + (j - 64) ** 2 + (i - 64) ** 2 <= (32 ** 2) ? CvColor::White : CvColor::Black + } + contours = mat0.find_contours + rect = contours.bounding_rect + assert_equal(CvRect, rect.class) + assert_equal(32, rect.x) + assert_equal(32, rect.y) + assert_equal(65, rect.width) + assert_equal(65, rect.height) + end + + def test_create_tree + mat0 = create_cvmat(128, 128, :cv8u, 1) { |j, i| + (j - 64) ** 2 + (i - 64) ** 2 <= (32 ** 2) ? CvColor::White : CvColor::Black + } + contour = mat0.find_contours + tree = contour.create_tree + assert_equal(CvContourTree, tree.class) + assert_equal(34, tree.p1.x) + assert_equal(53, tree.p1.y) + assert_equal(0, tree.p2.x) + assert_equal(0, tree.p2.y) + end + + def test_in + mat0 = create_cvmat(128, 128, :cv8u, 1) { |j, i| + (j - 64) ** 2 + (i - 64) ** 2 <= (32 ** 2) ? CvColor::White : CvColor::Black + } + contour = mat0.find_contours + assert(contour.in? CvPoint.new(64, 64)) + assert_false(contour.in? CvPoint.new(0, 0)) + assert_nil(contour.in? CvPoint.new(64, 32)) + end + + def test_measure_distance + mat0 = create_cvmat(128, 128, :cv8u, 1) { |j, i| + (j - 64) ** 2 + (i - 64) ** 2 <= (32 ** 2) ? CvColor::White : CvColor::Black + } + contour = mat0.find_contours + assert_in_delta(-0.7071, contour.measure_distance(CvPoint.new(63, 32)), 0.01) + assert_in_delta(31.01, contour.measure_distance(CvPoint.new(64, 64)), 0.01) + end + + def test_point_polygon_test + mat0 = create_cvmat(128, 128, :cv8u, 1) { |j, i| + (j - 64) ** 2 + (i - 64) ** 2 <= (32 ** 2) ? CvColor::White : CvColor::Black + } + contour = mat0.find_contours + + assert_equal(1, contour.point_polygon_test(CvPoint.new(64, 64), 0)) + assert_equal(1, contour.point_polygon_test(CvPoint.new(64, 64), false)) + assert_equal(-1, contour.point_polygon_test(CvPoint.new(0, 0), 0)) + assert_equal(-1, contour.point_polygon_test(CvPoint.new(0, 0), false)) + assert_equal(0, contour.point_polygon_test(CvPoint.new(64, 32), 0)) + assert_equal(0, contour.point_polygon_test(CvPoint.new(64, 32), false)) + + assert_in_delta(-0.7071, contour.point_polygon_test(CvPoint.new(63, 32), 1), 0.01) + assert_in_delta(-0.7071, contour.point_polygon_test(CvPoint.new(63, 32), true), 0.01) + assert_in_delta(31.01, contour.point_polygon_test(CvPoint.new(64, 64), 1), 0.01) + assert_in_delta(31.01, contour.point_polygon_test(CvPoint.new(64, 64), true), 0.01) + end + + def test_match_shapes + img1 = CvMat.load(FILENAME_CONTOURS, CV_LOAD_IMAGE_GRAYSCALE).threshold(127, 255, CV_THRESH_BINARY) + img2 = CvMat.load(FILENAME_LINES, CV_LOAD_IMAGE_GRAYSCALE).threshold(127, 255, CV_THRESH_BINARY) + c1 = img1.find_contours(mode: CV_RETR_EXTERNAL) + c2 = img2.find_contours(mode: CV_RETR_EXTERNAL) + + [CV_CONTOURS_MATCH_I1, CV_CONTOURS_MATCH_I2, CV_CONTOURS_MATCH_I3].each { |method| + assert_in_delta(0, c1.match_shapes(c1, method), 0.01) + assert_in_delta(0, c1.match_shapes(c1, method, nil), 0.01) + + assert(c1.match_shapes(c2, method) > 0) + assert(c1.match_shapes(c2, method, nil) > 0) + } + + assert_raise(TypeError) { + c1.match_shapes(DUMMY_OBJ, CV_CONTOURS_MATCH_I1) + } + assert_raise(TypeError) { + c1.match_shapes(c2, DUMMY_OBJ) + } + end +end diff --git a/test/test_cvcontourtree.rb b/test/test_cvcontourtree.rb new file mode 100755 index 00000000..9ab0dd7c --- /dev/null +++ b/test/test_cvcontourtree.rb @@ -0,0 +1,43 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvContourTree +class TestCvContourTree < OpenCVTestCase + def setup + @tree = CvContourTree.new(CV_SEQ_ELTYPE_POINT) + end + + def test_initialize + tree = CvContourTree.new(CV_SEQ_ELTYPE_POINT) + assert_equal(CvContourTree, tree.class) + assert(tree.is_a? CvSeq) + end + + def test_p1 + assert_equal(CvPoint, @tree.p1.class) + end + + def test_p2 + assert_equal(CvPoint, @tree.p2.class) + end + + def test_contour + mat0 = create_cvmat(128, 128, :cv8u, 1) { |j, i| + (j - 64) ** 2 + (i - 64) ** 2 <= (32 ** 2) ? CvColor::White : CvColor::Black + } + contour = mat0.find_contours + tree = contour.create_tree + contour = tree.contour(CvTermCriteria.new(100, 0.01)) + assert_equal(CvContour, contour.class) + + assert_raise(CvStsBadArg) { + tree.contour(CvTermCriteria.new(0, 0)) + } + end +end + diff --git a/test/test_cverror.rb b/test/test_cverror.rb new file mode 100755 index 00000000..aad01292 --- /dev/null +++ b/test/test_cverror.rb @@ -0,0 +1,50 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvError +class TestCvError < OpenCVTestCase + def test_cverror + assert_equal(StandardError, CvError.superclass) + begin + raise CvError + rescue + assert_equal(CvError, $!.class) + end + end + + def test_subclass + errors = [CvStsBackTrace, CvStsError, CvStsInternal, CvStsNoMem, CvStsBadArg, CvStsBadFunc, CvStsNoConv, CvStsAutoTrace, CvHeaderIsNull, CvBadImageSize, CvBadOffset, CvBadDataPtr, CvBadStep, CvBadModelOrChSeq, CvBadNumChannels, CvBadNumChannel1U, CvBadDepth, CvBadAlphaChannel, CvBadOrder, CvBadOrigin, CvBadAlign, CvBadCallBack, CvBadTileSize, CvBadCOI, CvBadROISize, CvMaskIsTiled, CvStsNullPtr, CvStsVecLengthErr, CvStsFilterStructContentErr, CvStsKernelStructContentErr, CvStsFilterOffsetErr, CvStsBadSize, CvStsDivByZero, CvStsInplaceNotSupported, CvStsObjectNotFound, CvStsUnmatchedFormats, CvStsBadFlag, CvStsBadPoint, CvStsBadMask, CvStsUnmatchedSizes, CvStsUnsupportedFormat, CvStsOutOfRange, CvStsParseError, CvStsNotImplemented, CvStsBadMemBlock, CvStsAssert, CvGpuNotSupported, CvGpuApiCallError] + + errors.each { |err| + assert_equal(CvError, err.superclass) + + begin + raise err + rescue err + assert_equal(err, $!.class) + rescue + flunk("Failed to catch #{err}") + end + + begin + raise err + rescue CvError + assert_equal(err, $!.class) + rescue + flunk("Failed to catch #{err}") + end + + begin + raise err + rescue + assert_equal(err, $!.class) + end + } + end +end + diff --git a/test/test_cvfeaturetree.rb b/test/test_cvfeaturetree.rb new file mode 100755 index 00000000..b1332984 --- /dev/null +++ b/test/test_cvfeaturetree.rb @@ -0,0 +1,65 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvFeatureTree +class TestCvFeatureTree < OpenCVTestCase + def test_initialize + desc = CvMat.new(1, 1, :cv32f, 1) + ft = CvFeatureTree.new(desc) + assert_equal(CvFeatureTree, ft.class) + + assert_raise(TypeError) { + CvFeatureTree.new(DUMMY_OBJ) + } + end + + def test_find_feature + dim = 2 + points = [] + points << [99, 51] + points << [52, 57] + points << [57, 42] + points << [13, 39] + points << [15, 68] + points << [75, 11] + points << [69, 62] + points << [52, 46] + points << [0, 64] + points << [67, 16] + + desc1 = CvMat.new(points.size, dim, :cv32f, 1) + desc1.set_data(points) + + pt = [[50, 50], [11, 40]] + desc2 = CvMat.new(pt.size, dim, :cv32f, 1) + desc2.set_data(pt) + + ft = CvFeatureTree.new(desc1) + results, dist = ft.find_features(desc2, 1, 10) + + assert_equal(CvMat, results.class) + assert_equal(CvMat, dist.class) + + assert_equal(7, results[0][0].to_i) + assert_in_delta(4.472, dist[0][0], 0.001) + + assert_equal(3, results[1][0].to_i) + assert_in_delta(2.236, dist[1][0], 0.001) + + assert_raise(TypeError) { + ft.find_features(DUMMY_OBJ, 1, 10) + } + assert_raise(TypeError) { + ft.find_features(desc2, DUMMY_OBJ, 10) + } + assert_raise(TypeError) { + ft.find_features(desc2, 1, DUMMY_OBJ) + } + end +end + diff --git a/test/test_cvfont.rb b/test/test_cvfont.rb new file mode 100755 index 00000000..5c71843c --- /dev/null +++ b/test/test_cvfont.rb @@ -0,0 +1,58 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvFont +class TestCvFont < OpenCVTestCase + def test_FACE + assert_equal(0, CvFont::FACE[:simplex]) + assert_equal(1, CvFont::FACE[:plain]) + assert_equal(2, CvFont::FACE[:duplex]) + assert_equal(4, CvFont::FACE[:triplex]) + assert_equal(5, CvFont::FACE[:complex_small]) + assert_equal(6, CvFont::FACE[:script_simplex]) + assert_equal(7, CvFont::FACE[:script_complex]) + end + + def test_FONT_OPTION + assert_equal(1.0, CvFont::FONT_OPTION[:hscale]) + assert_equal(1.0, CvFont::FONT_OPTION[:vscale]) + assert_equal(0, CvFont::FONT_OPTION[:shear]) + assert_equal(1, CvFont::FONT_OPTION[:thickness]) + assert_equal(8, CvFont::FONT_OPTION[:line_type]) + end + + def test_initialize + font = CvFont.new(:simplex) + assert_equal(0, font.face) + assert_equal(1.0, font.hscale) + assert_equal(1.0, font.vscale) + assert_equal(0, font.shear) + assert_equal(1, font.thickness) + assert_equal(8, font.line_type) + assert_false(font.italic) + + font = CvFont.new(:plain, :hscale => 2.5, :vscale => 3.5, + :shear => 0.5, :thickness => 3, :line_type => 2, :italic => false) + assert_equal(1, font.face) + assert_equal(2.5, font.hscale) + assert_equal(3.5, font.vscale) + assert_equal(0.5, font.shear) + assert_equal(3, font.thickness) + assert_equal(2, font.line_type) + assert_false(font.italic) + + font = CvFont.new(:simplex, :italic => true) + assert_equal(16, font.face) + assert(font.italic) + + assert_raise(ArgumentError) { + CvFont.new(:foo) + } + end +end + diff --git a/test/test_cvhaarclassifiercascade.rb b/test/test_cvhaarclassifiercascade.rb new file mode 100755 index 00000000..9e65c5b2 --- /dev/null +++ b/test/test_cvhaarclassifiercascade.rb @@ -0,0 +1,63 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvHaarClassifierCascade +class TestCvHaarClassifierCascade < OpenCVTestCase + def setup + @cascade = CvHaarClassifierCascade.load(HAARCASCADE_FRONTALFACE_ALT) + end + + def test_load + assert_equal(CvHaarClassifierCascade, @cascade.class) + assert_raise(ArgumentError) { + CvHaarClassifierCascade.load('not/exist.xml') + } + end + + def test_detect_objects + img = CvMat.load(FILENAME_LENA256x256) + + detected = @cascade.detect_objects(img) + assert_equal(CvSeq, detected.class) + assert_equal(1, detected.size) + assert_equal(CvAvgComp, detected[0].class) + assert_equal(106, detected[0].x) + assert_equal(100, detected[0].y) + assert_equal(89, detected[0].width) + assert_equal(89, detected[0].height) + assert_equal(48, detected[0].neighbors) + + detected = @cascade.detect_objects(img) { |face| + assert_equal(106, face.x) + assert_equal(100, face.y) + assert_equal(89, face.width) + assert_equal(89, face.height) + assert_equal(48, face.neighbors) + } + assert_equal(CvSeq, detected.class) + assert_equal(1, detected.size) + assert_equal(CvAvgComp, detected[0].class) + + detected = @cascade.detect_objects(img, :scale_factor => 2.0, :flags => CV_HAAR_DO_CANNY_PRUNING, + :min_neighbors => 5, :min_size => CvSize.new(10, 10), + :max_size => CvSize.new(100, 100)) + assert_equal(CvSeq, detected.class) + assert_equal(1, detected.size) + assert_equal(CvAvgComp, detected[0].class) + assert_equal(109, detected[0].x) + assert_equal(102, detected[0].y) + assert_equal(80, detected[0].width) + assert_equal(80, detected[0].height) + assert_equal(7, detected[0].neighbors) + + assert_raise(TypeError) { + @cascade.detect_objects('foo') + } + end +end + diff --git a/test/test_cvhistogram.rb b/test/test_cvhistogram.rb new file mode 100755 index 00000000..aa58353e --- /dev/null +++ b/test/test_cvhistogram.rb @@ -0,0 +1,271 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvHistogram +class TestCvHistogram < OpenCVTestCase + def setup + @img = IplImage.load(FILENAME_LENA32x32, 0) + + dim = 1 + sizes = [8] + ranges = [[0, 255]] + @hist1 = CvHistogram.new(dim, sizes, CV_HIST_ARRAY, ranges, true).calc_hist!([@img]) + + dim = 2 + sizes = [8, 16] + ranges = [[0, 255], [0, 255]] + @hist2 = CvHistogram.new(dim, sizes, CV_HIST_SPARSE, ranges, true).calc_hist!([@img, @img]) + end + + def teardown + @hist1 = nil + @hist2 = nil + GC.start + end + + def test_initialize + dim = 1 + sizes = [256] + ranges = [[0, 256]] + hist1 = CvHistogram.new(dim, sizes, CV_HIST_ARRAY, ranges, true) + hist2 = CvHistogram.new(dim, sizes, CV_HIST_ARRAY) + hist3 = CvHistogram.new(dim, sizes, CV_HIST_ARRAY, nil) + hist4 = CvHistogram.new(dim, sizes, CV_HIST_ARRAY, nil, false) + end + + def test_is_uniform + assert(@hist1.is_uniform?) + assert(@hist2.is_uniform?) + end + + def test_is_sparse + assert_false(@hist1.is_sparse?) + assert(@hist2.is_sparse?) + end + + def test_has_range + assert(@hist1.has_range?) + assert(@hist2.has_range?) + end + + def test_calc_hist + img = IplImage.new(1, 1, :cv8u, 1) + assert_equal(CvHistogram, @hist1.calc_hist([img]).class) + assert_equal(CvHistogram, @hist1.calc_hist([img, img]).class) + assert_equal(CvHistogram, @hist1.calc_hist([img], true).class) + assert_equal(CvHistogram, @hist1.calc_hist([img, img], false).class) + mask = CvMat.new(1, 1, :cv8u, 1) + assert_equal(CvHistogram, @hist1.calc_hist([img], true, mask).class) + + assert_raise(TypeError) { + @hist1.calc_hist(img) + } + assert_raise(TypeError) { + @hist1.calc_hist([DUMMY_OBJ]) + } + assert_raise(TypeError) { + @hist1.calc_hist(nil) + } + assert_raise(TypeError) { + @hist1.calc_hist([img], true, DUMMY_OBJ) + } + assert_raise(ArgumentError) { + @hist1.calc_hist([]) + } + end + + def test_aref + expected = [0.0, 102.0, 189.0, 244.0, 285.0, 140.0, 64.0, 0.0] + expected.each_with_index { |x, i| + assert_in_delta(x, @hist1[i], 0.001) + assert_in_delta(x, @hist1.query_hist_value(i), 0.001) + } + end + + def test_min_max_value + min, max, min_loc, max_loc = @hist1.min_max_value + assert_in_delta(0.0, min, 0.001) + assert_in_delta(285.0, max, 0.001) + assert_equal(Array, min_loc.class) + assert_equal(Array, max_loc.class) + assert_equal(1, min_loc.size) + assert_equal(1, max_loc.size) + assert_equal(0, min_loc[0]) + assert_equal(4, max_loc[0]) + + min, max, min_loc, max_loc = @hist2.min_max_value + assert_in_delta(14.0, min, 0.001) + assert_in_delta(158.0, max, 0.001) + assert_equal(Array, min_loc.class) + assert_equal(Array, max_loc.class) + assert_equal(2, min_loc.size) + assert_equal(2, max_loc.size) + assert_equal(1, min_loc[0]) + assert_equal(2, min_loc[1]) + assert_equal(4, max_loc[0]) + assert_equal(9, max_loc[1]) + end + + def test_dims + dims, sizes = @hist1.dims + assert_equal(1, dims) + assert_equal(Array, sizes.class) + assert_equal(1, sizes.size) + assert_equal(8, sizes[0]) + + dims, sizes = @hist2.dims + assert_equal(2, dims) + assert_equal(Array, sizes.class) + assert_equal(2, sizes.size) + assert_equal(8, sizes[0]) + assert_equal(16, sizes[1]) + end + + def test_copy_hist + expected = [0.0, 102.0, 189.0, 244.0, 285.0, 140.0, 64.0, 0.0] + hist = @hist1.copy_hist + expected.each_with_index { |x, i| + assert_in_delta(x, hist[i], 0.001) + assert_in_delta(x, hist.query_hist_value(i), 0.001) + } + end + + def test_clear_hist + @hist1.clear_hist! + dims, sizes = @hist1.dims + dims.times { |i| + assert_in_delta(0.0, @hist1[i], 0.001) + } + end + + def test_normalize_hist + @hist1.normalize_hist!(100) + expected = [0.0, 9.96, 18.46, 23.83, 27.83, 13.67, 6.25, 0.0] + expected.each_with_index { |x, i| + assert_in_delta(x, @hist1[i], 0.01) + } + end + + def test_thresh_hist + @hist1.thresh_hist!(150) + expected = [0.0, 0.0, 189.0, 244.0, 285.0, 0.0, 0.0, 0.0] + expected.each_with_index { |x, i| + assert_in_delta(x, @hist1[i], 0.001) + } + end + + def test_set_hist_bin_ranges + dim = 1 + sizes = [8] + + hist = CvHistogram.new(dim, sizes, CV_HIST_ARRAY) + assert_false(hist.has_range?) + assert(hist.is_uniform?) + + ranges = [[0, 255]] + hist.set_hist_bin_ranges!(ranges, true) + assert(hist.has_range?) + assert(hist.is_uniform?) + + assert_raise(TypeError) { + hist.set_hist_bin_ranges!(DUMMY_OBJ) + } + assert_raise(TypeError) { + hist.set_hist_bin_ranges!([DUMMY_OBJ]) + } + end + + def test_calc_back_project + back_project = @hist1.calc_back_project([@img]) + assert_equal(@img.class, back_project.class) + assert_equal('2a0097af1ab4f9343e4feaae3a780c93', hash_img(back_project)) + + assert_raise(TypeError) { + @hist1.calc_back_project(DUMMY_OBJ) + } + assert_raise(TypeError) { + @hist1.calc_back_project([DUMMY_OBJ]) + } + end + + def test_calc_back_project_patch + img = IplImage.load(FILENAME_LENA256x256, 0) + template = IplImage.load(FILENAME_LENA_EYES, 0) + + dim = 1 + sizes = [8] + ranges = [[0, 255]] + hist = CvHistogram.new(dim, sizes, CV_HIST_ARRAY, ranges).calc_hist!([template]) + back_project = hist.calc_back_project_patch([img], template.size, CV_COMP_CORREL, 1.0) + assert_equal('e6497e45c6f2f715328bbc2fefe31581', hash_img(back_project)) + + assert_raise(TypeError) { + hist.calc_back_project_patch(DUMMY_OBJ, template.size, CV_COMP_CORREL, 1.0) + } + assert_raise(TypeError) { + hist.calc_back_project_patch([DUMMY_OBJ], template.size, CV_COMP_CORREL, 1.0) + } + + # Uncomment the following line to show the result + # min_val, max_val, min_loc, max_loc = back_project.min_max_loc + # result = img.rectangle(max_loc, CvPoint.new(max_loc.x + template.width, max_loc.y + template.height), + # :thickness => 2) + # snap img, template, back_project, result + end + + def test_compare_hist + img = IplImage.load(FILENAME_CAT, 0) + dim, sizes = @hist1.dims + ranges = [[0, 255]] + hist = CvHistogram.new(dim, sizes, CV_HIST_ARRAY, ranges).calc_hist!([img]) + + assert_in_delta(0.7446, CvHistogram.compare_hist(@hist1, hist, CV_COMP_CORREL), 0.1) + assert_in_delta(30250343.0, CvHistogram.compare_hist(@hist1, hist, CV_COMP_CHISQR), 1.0) + assert_in_delta(1024.0, CvHistogram.compare_hist(@hist1, hist, CV_COMP_INTERSECT), 1.0) + assert_in_delta(0.2955, CvHistogram.compare_hist(@hist1, hist, CV_COMP_BHATTACHARYYA), 0.1) + + assert_raise(TypeError) { + CvHistogram.compare_hist(DUMMY_OBJ, hist, CV_COMP_CORREL) + } + assert_raise(TypeError) { + CvHistogram.compare_hist(@hist1, DUMMY_OBJ, CV_COMP_CORREL) + } + assert_raise(TypeError) { + CvHistogram.compare_hist(@hist1, hist, DUMMY_OBJ) + } + end + + def test_calc_prob_density + img = IplImage.load(FILENAME_CAT, 0) + dim, sizes = @hist1.dims + ranges = [[0, 255]] + hist = CvHistogram.new(dim, sizes, CV_HIST_ARRAY, ranges).calc_hist!([img]) + dst = CvHistogram.calc_prob_density(hist, @hist1) + + assert_equal(CvHistogram, dst.class) + dim, sizes = dst.dims + expected_dim, expected_sizes = @hist1.dims + assert_equal(expected_dim, dim) + expected_sizes.each_with_index { |x, i| + assert_equal(x, sizes[i]) + } + + expected = [0.0, 1.437, 1.135, 1.092, 2.323, 3.712, 3.103, 0.0] + expected.each_with_index { |x, i| + assert_in_delta(x, dst[i], 0.001) + } + + assert_raise(TypeError) { + CvHistogram.calc_prob_density(DUMMY_OBJ, @hist1) + } + assert_raise(TypeError) { + CvHistogram.calc_prob_density(hist, DUMMY_OBJ) + } + end +end + diff --git a/test/test_cvhumoments.rb b/test/test_cvhumoments.rb new file mode 100755 index 00000000..080f2396 --- /dev/null +++ b/test/test_cvhumoments.rb @@ -0,0 +1,83 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvHuMoment +class TestCvHuMoments < OpenCVTestCase + def setup + @mat = create_cvmat(128, 128, :cv8u, 1) { |j, i| + if j >= 32 and j < 96 and i >= 16 and i < 112 + CvScalar.new(0) + elsif j >= 16 and j < 112 and i >= 16 and i < 112 + CvScalar.new(128) + else + CvScalar.new(255) + end + } + @moment1 = CvMoments.new + @moment2 = CvMoments.new(nil, true) + @moment3 = CvMoments.new(@mat) + @moment4 = CvMoments.new(@mat, true) + + @hu_moments1 = CvHuMoments.new(@moment1) + @hu_moments2 = CvHuMoments.new(@moment2) + @hu_moments3 = CvHuMoments.new(@moment3) + @hu_moments4 = CvHuMoments.new(@moment4) + end + + def test_initialize + [@hu_moments1, @hu_moments2, @hu_moments3, @hu_moments4].each { |m| + assert_not_nil(m) + assert_equal(CvHuMoments, m.class) + } + + assert_raise(TypeError) { + CvHuMoments.new('foo') + } + end + + def test_huX + hu_moments = [@hu_moments1.hu1, @hu_moments1.hu2, @hu_moments1.hu3, @hu_moments1.hu4, + @hu_moments1.hu5, @hu_moments1.hu6, @hu_moments1.hu7] + hu_moments.each { |hu| + assert_in_delta(0.0, hu, 0.000001) + } + + hu_moments = [@hu_moments2.hu1, @hu_moments2.hu2, @hu_moments2.hu3, @hu_moments2.hu4, + @hu_moments2.hu5, @hu_moments2.hu6, @hu_moments2.hu7] + hu_moments.each { |hu| + assert_in_delta(0.0, hu, 0.000001) + } + + hu_moments = [@hu_moments3.hu2, @hu_moments3.hu3, @hu_moments3.hu4, + @hu_moments3.hu5, @hu_moments3.hu6, @hu_moments3.hu7] + assert_in_delta(0.001771, @hu_moments3.hu1, 0.000001) + hu_moments.each { |hu| + assert_in_delta(0.0, hu, 0.000001) + } + + hu_moments = [@hu_moments4.hu3, @hu_moments4.hu4, + @hu_moments4.hu5, @hu_moments4.hu6, @hu_moments4.hu7] + assert_in_delta(0.361650, @hu_moments4.hu1, 0.000001) + assert_in_delta(0.000625, @hu_moments4.hu2, 0.000001) + hu_moments.each { |hu| + assert_in_delta(0.0, hu, 0.000001) + } + end + + def test_to_ary + [@hu_moments4.to_ary, @hu_moments4.to_a].each { |hu_moments| + assert_equal(7, hu_moments.size) + assert_in_delta(0.361650, hu_moments[0], 0.000001) + assert_in_delta(0.000625, hu_moments[1], 0.000001) + hu_moments[2..7].each { |hu| + assert_in_delta(0.0, hu, 0.000001) + } + } + end +end + diff --git a/test/test_cvline.rb b/test/test_cvline.rb new file mode 100755 index 00000000..c372ab93 --- /dev/null +++ b/test/test_cvline.rb @@ -0,0 +1,50 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvLine +class TestCvLine < OpenCVTestCase + def setup + @line = CvLine.new + end + + def test_initialize + assert_not_nil(@line) + assert_equal(CvLine, @line.class) + end + + def test_rho + @line.rho = 0.0 + assert_in_delta(0.0, @line.rho, 0.001) + @line.rho = 3.14 + assert_in_delta(3.14, @line.rho, 0.001) + end + + def test_theta + @line.theta = 0.0 + assert_in_delta(0.0, @line.theta, 0.001) + @line.theta = 3.14 + assert_in_delta(3.14, @line.theta, 0.001) + end + + def test_aref_aset + @line[0] = 0.0 + @line[1] = 0.0 + assert_in_delta(0.0, @line[0], 0.001) + assert_in_delta(0.0, @line[1], 0.001) + + @line[0] = 3.14 + @line[1] = 2.71 + assert_in_delta(3.14, @line[0], 0.001) + assert_in_delta(2.71, @line[1], 0.001) + + assert_raise(IndexError) { + @line[2] = 1 + } + end +end + diff --git a/test/test_cvmat.rb b/test/test_cvmat.rb new file mode 100755 index 00000000..01875511 --- /dev/null +++ b/test/test_cvmat.rb @@ -0,0 +1,3036 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvMat +class TestCvMat < OpenCVTestCase + def test_initialize + m = CvMat.new(10, 20) + assert_equal(10, m.rows) + assert_equal(20, m.cols) + assert_equal(:cv8u, m.depth) + assert_equal(3, m.channel) + + depth_table = { + CV_8U => :cv8u, + CV_8S => :cv8s, + CV_16U => :cv16u, + CV_16S => :cv16s, + CV_32S => :cv32s, + CV_32F => :cv32f, + CV_64F => :cv64f + } + + [CV_8U, CV_8S, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F, + :cv8u, :cv8s, :cv16u, :cv16s, :cv32s, :cv32f, :cv64f].each { |depth| + [1, 2, 3, 4].each { |ch| + m = CvMat.new(10, 20, depth, ch) + assert_equal(10, m.rows) + assert_equal(20, m.cols) + depth = depth_table[depth] unless depth.is_a? Symbol + assert_equal(depth, m.depth) + assert_equal(ch, m.channel) + } + } + + assert_raise(TypeError) { + m = CvMat.new(DUMMY_OBJ, 20, :cv8u, 1) + } + assert_raise(TypeError) { + m = CvMat.new(10, DUMMY_OBJ, :cv8u, 1) + } + assert_raise(TypeError) { + m = CvMat.new(10, 20, :cv8u, DUMMY_OBJ) + } + end + + def test_load + mat = CvMat.load(FILENAME_CAT) + assert_equal(CvMat, mat.class) + assert_equal(375, mat.cols) + assert_equal(500, mat.rows) + assert_equal(:cv8u, mat.depth) + assert_equal(3, mat.channel) + assert_equal('ebc0b85d3ac44ea60181c997f35d13df', hash_img(mat)) + + mat = CvMat.load(FILENAME_CAT, CV_LOAD_IMAGE_GRAYSCALE) + assert_equal(CvMat, mat.class) + assert_equal(375, mat.cols) + assert_equal(500, mat.rows) + assert_equal(:cv8u, mat.depth) + assert_equal(1, mat.channel) + assert_equal('f0ae1d7f2d6b3a64d093e3181361f3a4', hash_img(mat)) + + mat = CvMat.load(FILENAME_CAT, CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR) + assert_equal(CvMat, mat.class) + assert_equal(375, mat.cols) + assert_equal(500, mat.rows) + assert_equal(:cv8u, mat.depth) + assert_equal(3, mat.channel) + assert_equal('ebc0b85d3ac44ea60181c997f35d13df', hash_img(mat)) + + assert_raise(ArgumentError) { + CvMat.load + } + assert_raise(TypeError) { + CvMat.load(DUMMY_OBJ) + } + assert_raise(TypeError) { + CvMat.load(FILENAME_CAT, DUMMY_OBJ) + } + assert_raise(StandardError) { + CvMat.load('file/does/not/exist') + } + end + + def test_save_image + filename_jpg = 'save_image_test.jpg' + filename_png = 'save_image_test.png' + m = CvMat.new(20, 20, :cv8u, 1) + + File.delete filename_jpg if File.exists? filename_jpg + m.save_image filename_jpg + assert(File.exists? filename_jpg) + + File.delete filename_jpg if File.exists? filename_jpg + m.save_image(filename_jpg, CV_IMWRITE_JPEG_QUALITY => 10) + assert(File.exists? filename_jpg) + + File.delete filename_png if File.exists? filename_png + m.save_image(filename_png, CV_IMWRITE_PNG_COMPRESSION => 9) + assert(File.exists? filename_png) + + # Alias + File.delete filename_jpg if File.exists? filename_jpg + m.save filename_jpg + assert(File.exists? filename_jpg) + + assert_raise(TypeError) { + m.save_image(DUMMY_OBJ) + } + assert_raise(TypeError) { + m.save_image(filename_jpg, DUMMY_OBJ) + } + + File.delete filename_jpg if File.exists? filename_jpg + File.delete filename_png if File.exists? filename_png + end + + def test_encode + mat = CvMat.load(FILENAME_CAT); + + jpg = mat.encode('.jpg') + assert_equal('JFIF', jpg[6, 4].map(&:chr).join) # Is jpeg format? + + jpg = mat.encode('.jpg', CV_IMWRITE_JPEG_QUALITY => 10) + assert_equal('JFIF', jpg[6, 4].map(&:chr).join) + + png = mat.encode('.png') + assert_equal('PNG', png[1, 3].map(&:chr).join) # Is png format? + + png = mat.encode('.png', CV_IMWRITE_PNG_COMPRESSION => 9) + assert_equal('PNG', png[1, 3].map(&:chr).join) + + assert_raise(TypeError) { + mat.encode(DUMMY_OBJ) + } + assert_raise(TypeError) { + mat.encode('.jpg', DUMMY_OBJ) + } + + # Uncomment the following lines to see the result images + # + # open('test-jpeg.jpg', 'wb') { |f| + # f.write jpg.pack("c*") + # } + # open('test-png.png', 'wb') { |f| + # f.write png.pack("c*") + # } + end + + def test_decode + data = nil + open(FILENAME_CAT, 'rb') { |f| + data = f.read + } + data_ary = data.unpack("c*") + data_mat = CvMat.new(1, data_ary.size).set_data(data_ary) + expected = CvMat.load(FILENAME_CAT) + + mat1 = CvMat.decode(data) + mat2 = CvMat.decode(data_ary) + mat3 = CvMat.decode(data_mat) + mat4 = CvMat.decode(data, CV_LOAD_IMAGE_COLOR) + mat5 = CvMat.decode(data_ary, CV_LOAD_IMAGE_COLOR) + mat6 = CvMat.decode(data_mat, CV_LOAD_IMAGE_COLOR) + expected_hash = hash_img(expected) + + [mat1, mat2, mat3, mat4, mat5, mat6].each { |mat| + assert_equal(CvMat, mat.class) + assert_equal(expected.rows, mat.rows) + assert_equal(expected.cols, mat.cols) + assert_equal(expected.channel, mat.channel) + assert_equal(expected_hash, hash_img(mat)) + } + + expected_c1 = CvMat.load(FILENAME_CAT, CV_LOAD_IMAGE_GRAYSCALE) + mat1c1 = CvMat.decode(data, CV_LOAD_IMAGE_GRAYSCALE) + mat2c1 = CvMat.decode(data_ary, CV_LOAD_IMAGE_GRAYSCALE) + mat3c1 = CvMat.decode(data_mat, CV_LOAD_IMAGE_GRAYSCALE) + expected_hash_c1 = hash_img(expected_c1) + + [mat1c1, mat2c1, mat3c1].each { |mat| + assert_equal(CvMat, mat.class) + assert_equal(expected_c1.rows, mat.rows) + assert_equal(expected_c1.cols, mat.cols) + assert_equal(expected_c1.channel, mat.channel) + assert_equal(expected_hash_c1, hash_img(mat)) + } + + assert_raise(TypeError) { + CvMat.decode(DUMMY_OBJ) + } + assert_raise(TypeError) { + CvMat.decode(data, DUMMY_OBJ) + } + + # Uncomment the following line to show the result images + # snap mat1, mat2, mat3 + end + + def test_GOOD_FEATURES_TO_TRACK_OPTION + assert_equal(0xff, CvMat::GOOD_FEATURES_TO_TRACK_OPTION[:max]) + assert_nil(CvMat::GOOD_FEATURES_TO_TRACK_OPTION[:mask]) + assert_equal(3, CvMat::GOOD_FEATURES_TO_TRACK_OPTION[:block_size]) + assert((not CvMat::GOOD_FEATURES_TO_TRACK_OPTION[:use_harris])) + assert_in_delta(0.04, CvMat::GOOD_FEATURES_TO_TRACK_OPTION[:k], 0.01) + end + + def test_FIND_CONTOURS_OPTION + assert_equal(1, CvMat::FIND_CONTOURS_OPTION[:mode]) + assert_equal(2, CvMat::FIND_CONTOURS_OPTION[:method]) + assert_equal(0, CvMat::FIND_CONTOURS_OPTION[:offset].x) + assert_equal(0, CvMat::FIND_CONTOURS_OPTION[:offset].y) + end + + def test_OPTICAL_FLOW_HS_OPTION + assert_in_delta(0.0005, CvMat::OPTICAL_FLOW_HS_OPTION[:lambda], 0.000001) + assert_equal(1, CvMat::OPTICAL_FLOW_HS_OPTION[:criteria].max) + assert_in_delta(0.001, CvMat::OPTICAL_FLOW_HS_OPTION[:criteria].eps, 0.00001) + end + + def test_OPTICAL_FLOW_BM_OPTION + assert_equal(4, CvMat::OPTICAL_FLOW_BM_OPTION[:block_size].width) + assert_equal(4, CvMat::OPTICAL_FLOW_BM_OPTION[:block_size].height) + assert_equal(1, CvMat::OPTICAL_FLOW_BM_OPTION[:shift_size].width) + assert_equal(1, CvMat::OPTICAL_FLOW_BM_OPTION[:shift_size].height) + assert_equal(4, CvMat::OPTICAL_FLOW_BM_OPTION[:max_range].width) + assert_equal(4, CvMat::OPTICAL_FLOW_BM_OPTION[:max_range].height) + end + + def test_FIND_FUNDAMENTAL_MAT_OPTION + assert((not CvMat::FIND_FUNDAMENTAL_MAT_OPTION[:with_status])) + assert_in_delta(1.0, CvMat::FIND_FUNDAMENTAL_MAT_OPTION[:maximum_distance], 0.01) + assert_in_delta(0.99, CvMat::FIND_FUNDAMENTAL_MAT_OPTION[:desirable_level], 0.01) + end + + def test_to_s + m = CvMat.new(10, 20) + assert_equal('', m.to_s) + m = CvMat.new(10, 20, :cv16s) + assert_equal('', m.to_s) + m = CvMat.new(10, 20, :cv32f, 1) + assert_equal('', m.to_s) + end + + def test_inside + m = CvMat.new(20, 10) + assert(m.inside? CvPoint.new(0, 0)) + assert(m.inside? CvPoint.new(9, 19)) + assert((not m.inside? CvPoint.new(10, 0))) + assert((not m.inside? CvPoint.new(0, 20))) + assert((not m.inside? CvPoint.new(10, 20))) + end + + def test_to_IplConvKernel + kernel = CvMat.new(10, 20).to_IplConvKernel(CvPoint.new(2, 3)) + assert_equal(10, kernel.rows) + assert_equal(20, kernel.cols) + assert_equal(2, kernel.anchor.x) + assert_equal(3, kernel.anchor.y) + assert_equal(2, kernel.anchor_x) + assert_equal(3, kernel.anchor_y) + end + + def test_create_mask + mask = CvMat.new(10, 20).create_mask + assert_equal(20, mask.width) + assert_equal(10, mask.height) + assert_equal(:cv8u, mask.depth) + assert_equal(1, mask.channel) + end + + def test_fields + m = CvMat.new(20, 10) + assert_equal(10, m.width) + assert_equal(10, m.columns) + assert_equal(10, m.cols) + assert_equal(20, m.height) + assert_equal(20, m.rows) + assert_equal(:cv8u, m.depth) + assert_equal(3, m.channel) + + m = CvMat.new(20, 10, :cv16s, 1) + assert_equal(10, m.width) + assert_equal(10, m.columns) + assert_equal(10, m.cols) + assert_equal(20, m.height) + assert_equal(20, m.rows) + assert_equal(:cv16s, m.depth) + assert_equal(1, m.channel) + end + + def test_clone + m1 = create_cvmat(10, 20) + m2 = m1.clone + assert_equal(m1.data, m2.data) + end + + def test_copy + m1 = create_cvmat(10, 20, CV_32F, 1) { |j, i, c| CvScalar.new(c) } + + m2 = m1.copy + assert_equal(m1.data, m2.data) + + m2 = create_cvmat(10, 20, CV_32F, 1).zero + m3 = m1.copy(m2) + assert_equal(m1.data, m2.data) + assert_equal(m1.data, m3.data) + + rows, cols = m1.rows, m1.cols + mask = create_cvmat(rows, cols, CV_8U, 1) { |j, i, c| + val = (i > cols / 2) ? 0 : 255 + CvScalar.new(val) + } + + m2_orig = m2.copy + m3 = m1.copy(m2, mask) + rows.times { |j| + cols.times { |i| + expected = (mask[j, i][0] == 0) ? m2_orig[j, i] : m1[j, i] + assert_cvscalar_equal(expected, m2[j, i]) + assert_cvscalar_equal(expected, m3[j, i]) + } + } + + assert_raise(TypeError) { + m1.copy(DUMMY_OBJ) + } + end + + def test_convert_depth + m = CvMat.new(10, 20, :cv32f) + assert_equal(:cv8u, m.to_8u.depth) + assert_equal(:cv8s, m.to_8s.depth) + assert_equal(:cv16u, m.to_16u.depth) + assert_equal(:cv16s, m.to_16s.depth) + assert_equal(:cv32s, m.to_32s.depth) + assert_equal(:cv32f, m.to_32f.depth) + assert_equal(:cv64f, m.to_64f.depth) + end + + def test_vector + m = CvMat.new(1, 2) + assert(m.vector?) + + m = CvMat.new(2, 2) + assert((not m.vector?)) + end + + def test_square + m = CvMat.new(2, 2) + assert(m.square?) + m = CvMat.new(1, 2) + assert((not m.square?)) + end + + def test_to_CvMat + m1 = CvMat.new(2, 3, :cv32f, 4) + m2 = m1.to_CvMat + assert_equal(CvMat, m2.class) + assert_equal(m1.rows, m2.rows) + assert_equal(m1.cols, m2.cols) + assert_equal(m1.depth, m2.depth) + assert_equal(m1.channel, m2.channel) + assert_equal(m1.data, m2.data) + end + + def test_sub_rect + m1 = create_cvmat(10, 10) + + assert_raise(ArgumentError) { + m1.sub_rect + } + + m2 = m1.sub_rect(CvRect.new(0, 0, 2, 3)) + assert_equal(2, m2.width) + assert_equal(3, m2.height) + m2.height.times { |j| + m2.width.times { |i| + assert_cvscalar_equal(m1[j, i], m2[j, i]) + } + } + + topleft = CvPoint.new(2, 3) + m2 = m1.sub_rect(topleft, CvSize.new(4, 5)) + assert_equal(4, m2.width) + assert_equal(5, m2.height) + m2.height.times { |j| + m2.width.times { |i| + assert_cvscalar_equal(m1[topleft.y + j, topleft.x + i], m2[j, i]) + } + } + + topleft = CvPoint.new(1, 2) + m2 = m1.sub_rect(topleft.x, topleft.y, 3, 4) + assert_equal(3, m2.width) + assert_equal(4, m2.height) + m2.height.times { |j| + m2.width.times { |i| + assert_cvscalar_equal(m1[topleft.y + j, topleft.x + i], m2[j, i]) + } + } + + # Alias + m2 = m1.subrect(CvRect.new(0, 0, 2, 3)) + assert_equal(2, m2.width) + assert_equal(3, m2.height) + m2.height.times { |j| + m2.width.times { |i| + assert_cvscalar_equal(m1[j, i], m2[j, i]) + } + } + + assert_raise(TypeError) { + m1.sub_rect(DUMMY_OBJ) + } + assert_raise(TypeError) { + m1.sub_rect(DUMMY_OBJ, CvSize.new(1, 2)) + } + assert_raise(TypeError) { + m1.sub_rect(CvPoint.new(1, 2), DUMMY_OBJ) + } + assert_raise(TypeError) { + m1.sub_rect(DUMMY_OBJ, 2, 3, 4) + } + assert_raise(TypeError) { + m1.sub_rect(1, DUMMY_OBJ, 3, 4) + } + assert_raise(TypeError) { + m1.sub_rect(1, 2, DUMMY_OBJ, 4) + } + assert_raise(TypeError) { + m1.sub_rect(1, 2, 3, DUMMY_OBJ) + } + end + + def test_get_rows + m1 = create_cvmat(10, 20) { |j, i, c| CvScalar.new(c) } + + row = 2 + m2 = m1.get_rows(row) + assert_equal(1, m2.rows) + assert_equal(m1.cols, m2.cols) + m1.cols.times { |i| + assert_cvscalar_equal(m1[row, i], m2[i]) + } + + row1 = 3..7 + row2 = 2...8 + [row1, row2].each { |row| + m3 = m1.get_rows(row) + w = (row.exclude_end?) ? row.last - row.begin : row.last - row.begin + 1 + assert_equal(w, m3.rows) + assert_equal(m1.cols, m3.cols) + + m3.rows.times { |j| + m3.cols.times { |i| + assert_cvscalar_equal(m1[row.begin + j, i], m3[j, i]) + } + } + } + + [row1, row2].each { |row| + delta = 2 + m3 = m1.get_rows(row, 2) + w = (((row.exclude_end?) ? row.last - row.begin : row.last - row.begin + 1).to_f / delta).ceil + assert_equal(w, m3.rows) + assert_equal(m1.cols, m3.cols) + + m3.rows.times { |j| + m3.cols.times { |i| + assert_cvscalar_equal(m1[row.begin + j * delta, i], m3[j, i]) + } + } + } + + assert_raise(TypeError) { + m1.get_rows(DUMMY_OBJ) + } + assert_raise(TypeError) { + m1.get_rows(1, DUMMY_OBJ) + } + end + + def test_get_cols + m1 = create_cvmat(10, 20) { |j, i, c| CvScalar.new(c) } + + col = 2 + m2 = m1.get_cols(col) + assert_equal(m1.rows, m2.rows) + assert_equal(1, m2.cols) + m1.height.times { |j| + assert_cvscalar_equal(m1[j, col], m2[j]) + } + + col1 = 3..7 + col2 = 2...8 + [col1, col2].each { |col| + m3 = m1.get_cols(col) + w = (col.exclude_end?) ? col.last - col.begin : col.last - col.begin + 1 + assert_equal(m1.rows, m3.rows) + assert_equal(w, m3.cols) + + m3.rows.times { |j| + m3.cols.times { |i| + assert_cvscalar_equal(m1[j, col.begin + i], m3[j, i]) + } + } + } + + assert_raise(TypeError) { + m1.get_cols(DUMMY_OBJ) + } + end + + def test_each_row + m1 = create_cvmat(2, 3) + a = [[1, 2, 3], [4, 5, 6]] + a.map! { |a1| + a1.map! { |a2| + CvScalar.new(a2, a2, a2, a2).to_ary + } + } + + j = 0 + m1.each_row { |r| + a[j].size.times { |i| + assert_cvscalar_equal(a[j][i], r[i]) + } + j += 1 + } + end + + def test_each_col + m1 = create_cvmat(2, 3) + a = [[1, 4], [2, 5], [3, 6]] + a.map! { |a1| + a1.map! { |a2| + CvScalar.new(a2, a2, a2, a2).to_ary + } + } + + j = 0 + m1.each_col { |c| + a[j].size.times { |i| + assert_cvscalar_equal(a[j][i], c[i]) + } + j += 1 + } + + # Alias + j = 0 + m1.each_column { |c| + a[j].size.times { |i| + assert_cvscalar_equal(a[j][i], c[i]) + } + j += 1 + } + end + + def test_diag + m = create_cvmat(5, 5) + a = [1, 7, 13, 19, 25].map { |x| CvScalar.new(x, x, x, x) } + d = m.diag + + a.each_with_index { |s, i| + assert_cvscalar_equal(s, d[i]) + } + + a = [2, 8, 14, 20].map { |x| CvScalar.new(x, x, x, x) } + d = m.diag(1) + a.each_with_index { |s, i| + assert_cvscalar_equal(s, d[i]) + } + + a = [6, 12, 18, 24].map { |x| CvScalar.new(x, x, x, x) } + d = m.diag(-1) + a.each_with_index { |s, i| + assert_cvscalar_equal(s, d[i]) + } + + # Alias + a = [1, 7, 13, 19, 25].map { |x| CvScalar.new(x, x, x, x) } + d = m.diagonal + a.each_with_index { |s, i| + assert_cvscalar_equal(s, d[i]) + } + + [m.rows, m.cols, -m.rows, -m.cols].each { |d| + assert_raise(CvStsOutOfRange) { + m.diag(d) + } + } + end + + def test_size + m = CvMat.new(2, 3) + assert_equal(3, m.size.width) + assert_equal(2, m.size.height) + end + + def test_dims + m = CvMat.new(2, 3) + assert_equal([2, 3], m.dims) + end + + def test_dim_size + m = CvMat.new(2, 3) + assert_equal(2, m.dim_size(0)) + assert_equal(3, m.dim_size(1)) + + assert_raise(TypeError) { + m.dim_size(DUMMY_OBJ) + } + end + + def test_aref + m = create_cvmat(2, 3) + assert_cvscalar_equal(CvScalar.new(1, 1, 1, 1), m[0]) + assert_cvscalar_equal(CvScalar.new(5, 5, 5, 5), m[4]) + assert_cvscalar_equal(CvScalar.new(2, 2, 2, 2), m[0, 1]) + assert_cvscalar_equal(CvScalar.new(4, 4, 4, 4), m[1, 0]) + assert_cvscalar_equal(CvScalar.new(2, 2, 2, 2), m[0, 1, 2]) + assert_cvscalar_equal(CvScalar.new(4, 4, 4, 4), m[1, 0, 3, 4]) + + # Alias + assert_cvscalar_equal(CvScalar.new(1, 1, 1, 1), m.at(0)) + + assert_raise(TypeError) { + m[DUMMY_OBJ] + } + + assert_raise(CvStsOutOfRange) { + m[-1] + } + assert_raise(CvStsOutOfRange) { + m[6] + } + assert_raise(CvStsOutOfRange) { + m[2, 2] + } + assert_raise(CvStsOutOfRange) { + m[1, 3] + } + assert_raise(CvStsOutOfRange) { + m[2, 2, 1] + } + assert_raise(CvStsOutOfRange) { + m[1, 3, 1] + } + end + + def test_aset + m = create_cvmat(2, 3) + m[0] = CvScalar.new(10, 10, 10, 10) + assert_cvscalar_equal(CvScalar.new(10, 10, 10, 10), m[0]) + m[1, 0] = CvScalar.new(20, 20, 20, 20) + assert_cvscalar_equal(CvScalar.new(20, 20, 20, 20), m[1, 0]) + m[1, 0, 2] = CvScalar.new(4, 4, 4, 4) + assert_cvscalar_equal(CvScalar.new(4, 4, 4, 4), m[1, 0]) + m[1, 0, 2, 4] = CvScalar.new(5, 5, 5, 5) + assert_cvscalar_equal(CvScalar.new(5, 5, 5, 5), m[1, 0]) + + assert_raise(TypeError) { + m[DUMMY_OBJ] = CvScalar.new(10, 10, 10, 10) + } + assert_raise(TypeError) { + m[0] = DUMMY_OBJ + } + + assert_raise(CvStsOutOfRange) { + m[-1] + } + assert_raise(CvStsOutOfRange) { + m[6] + } + assert_raise(CvStsOutOfRange) { + m[2, 2] + } + assert_raise(CvStsOutOfRange) { + m[1, 3] + } + assert_raise(CvStsOutOfRange) { + m[2, 2, 1] + } + assert_raise(CvStsOutOfRange) { + m[1, 3, 1] + } + end + + def test_set_data + [CV_8U, CV_8S, CV_16U, CV_16S, CV_32S].each { |depth| + a = [10, 20, 30, 40, 50, 60] + m = CvMat.new(2, 3, depth, 1) + m.set_data(a) + (m.rows * m.cols).times { |i| + assert_equal(a[i], m[i][0]) + } + } + + [CV_32F, CV_64F].each { |depth| + a = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6] + m = CvMat.new(2, 3, depth, 1) + m.set_data(a) + (m.rows * m.cols).times { |i| + assert_in_delta(a[i], m[i][0], 1.0e-5) + } + } + + a = [[10, 20, 30], [40, 50, 60]] + m = CvMat.new(2, 3, CV_8U, 1) + m.set_data(a) + (m.rows * m.cols).times { |i| + assert_equal(a.flatten[i], m[i][0]) + } + + [CV_8U, CV_8S, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F].each { |depth| + m = CvMat.new(2, 3, depth, 1) + assert_raise(TypeError) { + a = [DUMMY_OBJ] * 6 + m.set_data(a) + } + } + end + + def test_fill + m1 = create_cvmat(2, 3) + m2 = m1.fill(CvScalar.new(1, 2, 3, 4)) + m1.fill!(CvScalar.new(1, 2, 3, 4)) + m2.height.times { |j| + m2.width.times { |i| + assert_cvscalar_equal(CvScalar.new(1, 2, 3, 4), m1[j, i]) + assert_cvscalar_equal(CvScalar.new(1, 2, 3, 4), m2[j, i]) + } + } + + m1 = create_cvmat(5, 5) + m0 = m1.clone + mask = CvMat.new(m1.height, m1.width, :cv8u, 1).clear + 2.times { |j| + 2.times { |i| + mask[j, i] = CvScalar.new(1, 1, 1, 1) + } + } + + m2 = m1.fill(CvScalar.new(1, 2, 3, 4), mask) + m1.fill!(CvScalar.new(1, 2, 3, 4), mask) + m2.height.times { |j| + m2.width.times { |i| + if i < 2 and j < 2 + assert_cvscalar_equal(CvScalar.new(1, 2, 3, 4), m1[j, i]) + assert_cvscalar_equal(CvScalar.new(1, 2, 3, 4), m2[j, i]) + else + assert_cvscalar_equal(m0[j, i], m1[j, i]) + assert_cvscalar_equal(m0[j, i], m2[j, i]) + end + } + } + + # Alias + m1 = create_cvmat(2, 3) + m2 = m1.set(CvScalar.new(1, 2, 3, 4)) + m1.set!(CvScalar.new(1, 2, 3, 4)) + m2.height.times { |j| + m2.width.times { |i| + assert_cvscalar_equal(CvScalar.new(1, 2, 3, 4), m1[j, i]) + assert_cvscalar_equal(CvScalar.new(1, 2, 3, 4), m2[j, i]) + } + } + + m1 = create_cvmat(5, 5) + m0 = m1.clone + mask = CvMat.new(m1.height, m1.width, CV_8U, 1).clear + 2.times { |j| + 2.times { |i| + mask[j, i] = CvScalar.new(1, 1, 1, 1) + } + } + + m2 = m1.set(CvScalar.new(1, 2, 3, 4), mask) + m1.set!(CvScalar.new(1, 2, 3, 4), mask) + m2.height.times { |j| + m2.width.times { |i| + if i < 2 and j < 2 + assert_cvscalar_equal(CvScalar.new(1, 2, 3, 4), m1[j, i]) + assert_cvscalar_equal(CvScalar.new(1, 2, 3, 4), m2[j, i]) + else + assert_cvscalar_equal(m0[j, i], m1[j, i]) + assert_cvscalar_equal(m0[j, i], m2[j, i]) + end + } + } + + assert_raise(TypeError) { + m1.fill(DUMMY_OBJ) + } + assert_raise(TypeError) { + m1.fill(CvScalar.new(1), DUMMY_OBJ) + } + end + + def test_clear + m1 = create_cvmat(2, 3) + m2 = m1.clear + m1.clear! + m2.height.times { |j| + m2.width.times { |i| + assert_cvscalar_equal(CvScalar.new(0, 0, 0, 0), m1[j, i]) + assert_cvscalar_equal(CvScalar.new(0, 0, 0, 0), m2[j, i]) + } + } + + # Alias + m1 = create_cvmat(2, 3) + m2 = m1.set_zero + m1.set_zero! + m3 = create_cvmat(2, 3) + m4 = m3.zero + m3.zero! + m2.height.times { |j| + m2.width.times { |i| + assert_cvscalar_equal(CvScalar.new(0, 0, 0, 0), m1[j, i]) + assert_cvscalar_equal(CvScalar.new(0, 0, 0, 0), m2[j, i]) + assert_cvscalar_equal(CvScalar.new(0, 0, 0, 0), m3[j, i]) + assert_cvscalar_equal(CvScalar.new(0, 0, 0, 0), m4[j, i]) + } + } + end + + def test_identity + m1 = create_cvmat(5, 5) + m2 = m1.identity + m1.identity! + m2.height.times { |j| + m2.width.times { |i| + if i == j + assert_cvscalar_equal(CvScalar.new(1, 0, 0, 0), m1[j, i]) + assert_cvscalar_equal(CvScalar.new(1, 0, 0, 0), m2[j, i]) + else + assert_cvscalar_equal(CvScalar.new(0, 0, 0, 0), m1[j, i]) + assert_cvscalar_equal(CvScalar.new(0, 0, 0, 0), m2[j, i]) + end + } + } + + m1 = CvMat.new(5, 5, :cv8u, 4) + s = CvScalar.new(1, 2, 3, 4) + m2 = m1.identity(s) + m1.identity!(s) + m2.height.times { |j| + m2.width.times { |i| + if i == j + assert_cvscalar_equal(s, m1[j, i]) + assert_cvscalar_equal(s, m2[j, i]) + else + assert_cvscalar_equal(CvScalar.new(0, 0, 0, 0), m1[j, i]) + assert_cvscalar_equal(CvScalar.new(0, 0, 0, 0), m2[j, i]) + end + } + } + + assert_raise(TypeError) { + m1.identity(DUMMY_OBJ) + } + end + + def test_range + m1 = CvMat.new(1, 10, CV_32S, 1) + m2 = m1.range(0, m1.cols) + m1.range!(0, m1.cols) + m2.width.times { |i| + assert_cvscalar_equal(CvScalar.new(i, 0, 0, 0), m1[0, i]) + assert_cvscalar_equal(CvScalar.new(i, 0, 0, 0), m2[0, i]) + } + + assert_raise(TypeError) { + m1.range(DUMMY_OBJ, 2) + } + assert_raise(TypeError) { + m1.range(1, DUMMY_OBJ) + } + end + + def test_reshape + m = create_cvmat(2, 3, CV_8U, 3) + + vec = m.reshape(0, 1) + assert_equal(6, vec.width) + assert_equal(1, vec.height) + size = m.width * m.height + size.times { |i| + assert_cvscalar_equal(m[i], vec[i]) + } + + ch1 = m.reshape(1) + assert_equal(9, ch1.width) + assert_equal(2, ch1.height) + + m.height.times { |j| + m.width.times { |i| + s1 = ch1[j, i * 3][0] + s2 = ch1[j, i * 3 + 1][0] + s3 = ch1[j, i * 3 + 2][0] + assert_cvscalar_equal(m[j, i], CvScalar.new(s1, s2, s3, 0)) + } + } + + assert_raise(TypeError) { + m.reshape(DUMMY_OBJ) + } + assert_raise(TypeError) { + m.reshape(0, DUMMY_OBJ) + } + end + + def test_repeat + m1 = create_cvmat(2, 3, :cv8u, 3) + m2 = CvMat.new(6, 9, :cv8u, 3) + m2 = m1.repeat(m2) + m2.height.times { |j| + m2.width.times { |i| + a = m1[j % m1.height, i % m1.width] + assert_cvscalar_equal(m2[j, i], a) + } + } + assert_raise(TypeError) { + m1.repeat(DUMMY_OBJ) + } + end + + def test_flip + m0 = create_cvmat(2, 3) + + m1 = m0.clone + m1.flip!(:x) + m2 = m0.flip(:x) + m3 = m0.clone + m3.flip!(:y) + m4 = m0.flip(:y) + m5 = m0.clone + m5.flip!(:xy) + m6 = m0.flip(:xy) + m7 = m0.clone + m7.flip! + m8 = m0.flip + + [m1, m2, m3, m4, m5, m6, m7, m8].each { |m| + assert_equal(m0.height, m.height) + assert_equal(m0.width, m.width) + } + m0.height.times { |j| + m0.width.times { |i| + ri = m0.width - i - 1 + rj = m0.height - j - 1 + assert_cvscalar_equal(m0[j, ri], m1[j, i]) + assert_cvscalar_equal(m0[j, ri], m2[j, i]) + assert_cvscalar_equal(m0[rj, i], m3[j, i]) + assert_cvscalar_equal(m0[rj, i], m4[j, i]) + assert_cvscalar_equal(m0[rj, ri], m5[j, i]) + assert_cvscalar_equal(m0[rj, ri], m6[j, i]) + assert_cvscalar_equal(m0[j, ri], m7[j, i]) + assert_cvscalar_equal(m0[j, ri], m8[j, i]) + } + } + + assert_raise(TypeError) { + m0.flip(DUMMY_OBJ) + } + assert_raise(TypeError) { + m0.flip!(DUMMY_OBJ) + } + end + + def test_split + m0 = create_cvmat(2, 3, :cv8u, 3) { |j, i, c| + CvScalar.new(c * 10, c * 20, c * 30) + } + + splitted = m0.split + assert_equal(m0.channel, splitted.size) + splitted.each_with_index { |m, idx| + assert_equal(CvMat, m.class) + assert_equal(m0.height, m.height) + assert_equal(m0.width, m.width) + assert_equal(1, m.channel) + + c = 0 + m0.height.times { |j| + m0.width.times { |i| + val = c * 10 * (idx + 1) + assert_cvscalar_equal(CvScalar.new(val), m[j, i]) + c += 1 + } + } + } + + # IplImage#split should return Array + image = create_iplimage(2, 3, :cv8u, 3) { |j, i, c| + CvScalar.new(c * 10, c * 20, c * 30) + } + + splitted = image.split + assert_equal(3, splitted.size) + splitted.each_with_index { |img, channel| + assert_equal(IplImage, img.class) + assert_equal(image.height, img.height) + assert_equal(image.width, img.width) + assert_equal(1, img.channel) + + img.height.times { |j| + img.width.times { |i| + val = image[j, i][channel] + assert_cvscalar_equal(CvScalar.new(val), img[j, i]) + } + } + } + end + + def test_merge + m0 = create_cvmat(2, 3, :cv8u, 4) { |j, i, c| + CvScalar.new(c * 10, c * 20, c * 30, c * 40) + } + m1 = create_cvmat(2, 3, :cv8u, 1) { |j, i, c| + CvScalar.new(c * 10) + } + m2 = create_cvmat(2, 3, :cv8u, 1) { |j, i, c| + CvScalar.new(c * 20) + } + m3 = create_cvmat(2, 3, :cv8u, 1) { |j, i, c| + CvScalar.new(c * 30) + } + m4 = create_cvmat(2, 3, :cv8u, 1) { |j, i, c| + CvScalar.new(c * 40) + } + + m = CvMat.merge(m1, m2, m3, m4) + + assert_equal(m0.height, m.height) + assert_equal(m0.width, m.width) + m0.height.times { |j| + m0.width.times { |i| + assert_cvscalar_equal(m0[j, i], m[j, i]) + } + } + + m5 = create_cvmat(2, 3, :cv8u, 1) { |j, i, c| + CvScalar.new(c * 50) + } + + assert_raise(TypeError) { + CvMat.merge(DUMMY_OBJ) + } + assert_raise(ArgumentError) { + CvMat.merge + } + assert_raise(ArgumentError) { + CvMat.merge(m1, m2, m3, m4, m5) + } + assert_raise(ArgumentError) { + CvMat.merge(CvMat.new(1, 2, :cv8u, 2)) + } + assert_raise(ArgumentError) { + CvMat.merge(CvMat.new(1, 2, :cv8u, 1), + CvMat.new(2, 2, :cv8u, 1)) + } + assert_raise(ArgumentError) { + CvMat.merge(CvMat.new(1, 2, :cv8u, 1), + CvMat.new(1, 2, :cv32f, 1)) + } + end + + def test_rand_shuffle + m0 = create_cvmat(2, 3) + m1 = m0.clone + m1.rand_shuffle! + m2 = m0.rand_shuffle + m3 = m0.clone + m3.rand_shuffle!(123, 234) + m4 = m0.rand_shuffle(123, 234) + + assert_shuffled_equal = lambda { |src, shuffled| + assert_equal(src.width, shuffled.width) + assert_equal(src.height, shuffled.height) + mat0, mat1 = [], [] + src.height { |j| + src.width { |i| + mat0 << src[j, i].to_s + mat1 << shuffled[j, i].to_s + } + } + assert_equal(0, (mat0 - mat1).size) + } + + [m1, m2, m3, m4].each { |m| + assert_shuffled_equal.call(m0, m) + } + + assert_raise(TypeError) { + m0.rand_shuffle(DUMMY_OBJ) + } + assert_raise(TypeError) { + m0.rand_shuffle(123, DUMMY_OBJ) + } + end + + def test_lut + m0 = create_cvmat(2, 3, :cv8u, 3) + lut_mat = create_cvmat(1, 256, :cv8u, 3) { |j, i, c| + CvScalar.new(255 - c, 255 - c, 255 - c) + } + + m = m0.lut(lut_mat) + assert_equal(m0.height, m.height) + assert_equal(m0.width, m.width) + m0.height.times { |j| + m0.width.times { |i| + r, g, b = m0[j, i].to_ary.map { |c| 255 - c } + assert_cvscalar_equal(CvScalar.new(r, g, b, 0), m[j, i]) + } + } + + assert_raise(TypeError) { + m0.lut(DUMMY_OBJ) + } + end + + def test_convert_scale + m0 = create_cvmat(2, 3, :cv32f, 4) { |j, i, c| + CvScalar.new(-c, -c, -c, -c) + } + + m1 = m0.convert_scale(:depth => :cv8u) + m2 = m0.convert_scale(:scale => 1.5) + m3 = m0.convert_scale(:shift => 10.0) + m4 = m0.convert_scale(:depth => CV_16U) + + [m1, m2, m3, m4].each { |m| + assert_equal(m0.height, m.height) + assert_equal(m0.width, m.width) + } + m0.height.times { |j| + m0.width.times { |i| + assert_cvscalar_equal(CvScalar.new(0, 0, 0, 0), m1[j, i]) + a = m0[j, i].to_ary.map { |x| x * 1.5 } + assert_in_delta(a, m2[j, i], 0.001) + a = m0[j, i].to_ary.map { |x| x + 10.0 } + assert_in_delta(a, m3[j, i], 0.001) + assert_cvscalar_equal(CvScalar.new(0, 0, 0, 0), m4[j, i]) + } + } + + assert_raise(TypeError) { + m0.convert_scale(DUMMY_OBJ) + } + end + + def test_convert_scale_abs + m0 = create_cvmat(2, 3, :cv8u, 4) { |j, i, c| + CvScalar.new(c, c, c, c) + } + + m1 = m0.convert_scale_abs(:depth => :cv64f) + m2 = m0.convert_scale_abs(:scale => 2) + m3 = m0.convert_scale_abs(:shift => 10.0) + m4 = m0.convert_scale_abs(:depth => CV_64F) + + [m1, m2, m3, m4].each { |m| + assert_equal(m0.height, m.height) + assert_equal(m0.width, m.width) + } + m0.height.times { |j| + m0.width.times { |i| + assert_cvscalar_equal(m0[j, i], m1[j, i]) + a = m0[j, i].to_ary.map { |x| (x * 2).abs } + assert_in_delta(a, m2[j, i], 0.001) + a = m0[j, i].to_ary.map { |x| (x + 10.0).abs } + assert_in_delta(a, m3[j, i], 0.001) + assert_cvscalar_equal(m0[j, i], m4[j, i]) + } + } + + assert_raise(TypeError) { + m0.convert_scale(DUMMY_OBJ) + } + end + + def test_add + m1 = create_cvmat(6, 4, :cv32f, 4) { |j, i, c| + CvScalar.new(c * 0.1, c * 0.2, c * 0.3, c * 0.4) + } + m2 = create_cvmat(6, 4, :cv32f, 4) { |j, i, c| + CvScalar.new(c * 1, c * 2, c * 3, c * 4) + } + + # CvMat + CvMat + m3 = m1.add(m2) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + n = 0 + m1.height.times { |j| + m1.width.times { |i| + s = CvScalar.new(n * 1.1, n * 2.2, n * 3.3, n * 4.4) + assert_in_delta(s, m3[j, i], 0.001) + n += 1 + } + } + + # CvMat + CvScalar + s1 = CvScalar.new(1, 2, 3, 4) + m3 = m1.add(s1) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + n = 0 + m1.height.times { |j| + m1.width.times { |i| + s = CvScalar.new(n * 0.1 + 1, n * 0.2 + 2, n * 0.3 + 3, n * 0.4 + 4) + assert_in_delta(s, m3[j, i], 0.001) + n += 1 + } + } + + # Alias + m3 = m1 + m2 + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + n = 0 + m1.height.times { |j| + m1.width.times { |i| + s = CvScalar.new(n * 1.1, n * 2.2, n * 3.3, n * 4.4) + assert_in_delta(s, m3[j, i], 0.001) + n += 1 + } + } + + # CvMat + CvMat with Mask + mask = create_cvmat(6, 4, :cv8u, 1) { |j, i, c| + (i < 3 and j < 2) ? 1 : 0 + } + + m4 = m1.add(m2, mask) + assert_equal(m1.height, m4.height) + assert_equal(m1.width, m4.width) + n = 0 + m1.height.times { |j| + m1.width.times { |i| + if i < 3 and j < 2 + s = CvScalar.new(n * 1.1, n * 2.2, n * 3.3, n * 4.4) + else + s = m1[j, i] + end + assert_in_delta(s, m4[j, i], 0.001) + n += 1 + } + } + + # CvMat + CvScalar with Mask + m4 = m1.add(s1, mask) + assert_equal(m1.height, m4.height) + assert_equal(m1.width, m4.width) + n = 0 + m1.height.times { |j| + m1.width.times { |i| + if i < 3 and j < 2 + s = CvScalar.new(n * 0.1 + 1, n * 0.2 + 2, n * 0.3 + 3, n * 0.4 + 4) + else + s = m1[j, i] + end + assert_in_delta(s, m4[j, i], 0.001) + n += 1 + } + } + + assert_raise(TypeError) { + m1.add(DUMMY_OBJ) + } + assert_raise(TypeError) { + m1.add(CvScalar.new(1), DUMMY_OBJ) + } + end + + def test_sub + m1 = create_cvmat(6, 4, :cv32f, 4) { |j, i, c| + CvScalar.new(c * 0.1, c * 0.2, c * 0.3, c * 0.4) + } + m2 = create_cvmat(6, 4, :cv32f, 4) { |j, i, c| + CvScalar.new(c * 1, c * 2, c * 3, c * 4) + } + + # CvMat - CvMat + m3 = m1.sub(m2) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + n = 0 + m1.height.times { |j| + m1.width.times { |i| + s = CvScalar.new(-n * 0.9, -n * 1.8, -n * 2.7, -n * 3.6) + assert_in_delta(s, m3[j, i], 0.001) + n += 1 + } + } + + # CvMat - CvScalar + s1 = CvScalar.new(1, 2, 3, 4) + m3 = m1.sub(s1) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + n = 0 + m1.height.times { |j| + m1.width.times { |i| + s = CvScalar.new(n * 0.1 - 1, n * 0.2 - 2, n * 0.3 - 3, n * 0.4 - 4) + assert_in_delta(s, m3[j, i], 0.001) + n += 1 + } + } + + # Alias + m3 = m1 - m2 + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + n = 0 + m1.height.times { |j| + m1.width.times { |i| + s = CvScalar.new(-n * 0.9, -n * 1.8, -n * 2.7, -n * 3.6) + assert_in_delta(s, m3[j, i], 0.001) + n += 1 + } + } + + mask = create_cvmat(6, 4, :cv8u, 1) { |j, i, c| + (i < 3 and j < 2) ? 1 : 0 + } + + # CvMat - CvMat with Mask + m4 = m1.sub(m2, mask) + assert_equal(m1.height, m4.height) + assert_equal(m1.width, m4.width) + n = 0 + m1.height.times { |j| + m1.width.times { |i| + if i < 3 and j < 2 + s = CvScalar.new(-n * 0.9, -n * 1.8, -n * 2.7, -n * 3.6) + else + s = m1[j, i] + end + assert_in_delta(s, m4[j, i], 0.001) + n += 1 + } + } + + # CvMat - CvScalar with Mask + m4 = m1.sub(s1, mask) + assert_equal(m1.height, m4.height) + assert_equal(m1.width, m4.width) + n = 0 + m1.height.times { |j| + m1.width.times { |i| + if i < 3 and j < 2 + s = CvScalar.new(n * 0.1 - 1, n * 0.2 - 2, n * 0.3 - 3, n * 0.4 - 4) + else + s = m1[j, i] + end + assert_in_delta(s, m4[j, i], 0.001) + n += 1 + } + } + + assert_raise(TypeError) { + m1.sub(DUMMY_OBJ) + } + assert_raise(TypeError) { + m1.sub(CvScalar.new(1), DUMMY_OBJ) + } + end + + def test_mul + m1 = create_cvmat(3, 3, :cv32f) + s1 = CvScalar.new(0.1, 0.2, 0.3, 0.4) + m2 = create_cvmat(3, 3, :cv32f) { s1 } + + # CvMat * CvMat + m3 = m1.mul(m2) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3, 0.001) { |j, i, c| + n = c + 1 + CvScalar.new(n * 0.1, n * 0.2, n * 0.3, n * 0.4) + } + + # CvMat * CvMat * scale + scale = 2.5 + m3 = m1.mul(m2, scale) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3, 0.001) { |j, i, c| + n = (c + 1) * scale + CvScalar.new(n * 0.1, n * 0.2, n * 0.3, n * 0.4) + } + + # CvMat * CvScalar + scale = 2.5 + m3 = m1.mul(s1) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3, 0.001) { |j, i, c| + n = c + 1 + CvScalar.new(n * 0.1, n * 0.2, n * 0.3, n * 0.4) + } + + # CvMat * CvScalar * scale + m3 = m1.mul(s1, scale) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3, 0.001) { |j, i, c| + n = (c + 1) * scale + CvScalar.new(n * 0.1, n * 0.2, n * 0.3, n * 0.4) + } + + assert_raise(TypeError) { + m1.mul(DUMMY_OBJ) + } + assert_raise(TypeError) { + m1.mul(m2, DUMMY_OBJ) + } + end + + def test_mat_mul + m0 = create_cvmat(3, 3, :cv32f, 1) { |j, i, c| + CvScalar.new(c * 0.1) + } + m1 = create_cvmat(3, 3, :cv32f, 1) { |j, i, c| + CvScalar.new(c) + } + m2 = create_cvmat(3, 3, :cv32f, 1) { |j, i, c| + CvScalar.new(c + 1) + } + + m3 = m0.mat_mul(m1) + m4 = m0 * m1 + + [m3, m4].each { |m| + assert_equal(m1.width, m.width) + assert_equal(m1.height, m.height) + assert_in_delta(1.5, m[0, 0][0], 0.001) + assert_in_delta(1.8, m[0, 1][0], 0.001) + assert_in_delta(2.1, m[0, 2][0], 0.001) + assert_in_delta(4.2, m[1, 0][0], 0.001) + assert_in_delta(5.4, m[1, 1][0], 0.001) + assert_in_delta(6.6, m[1, 2][0], 0.001) + assert_in_delta(6.9, m[2, 0][0], 0.001) + assert_in_delta(9, m[2, 1][0], 0.001) + assert_in_delta(11.1, m[2, 2][0], 0.001) + } + + m5 = m0.mat_mul(m1, m2) + [m5].each { |m| + assert_equal(m1.width, m.width) + assert_equal(m1.height, m.height) + assert_in_delta(2.5, m[0, 0][0], 0.001) + assert_in_delta(3.8, m[0, 1][0], 0.001) + assert_in_delta(5.1, m[0, 2][0], 0.001) + assert_in_delta(8.2, m[1, 0][0], 0.001) + assert_in_delta(10.4, m[1, 1][0], 0.001) + assert_in_delta(12.6, m[1, 2][0], 0.001) + assert_in_delta(13.9, m[2, 0][0], 0.001) + assert_in_delta(17, m[2, 1][0], 0.001) + assert_in_delta(20.1, m[2, 2][0], 0.001) + } + + assert_raise(TypeError) { + m0.mat_mul(DUMMY_OBJ) + } + assert_raise(TypeError) { + m0.mat_mul(m1, DUMMY_OBJ) + } + end + + def test_div + m1 = create_cvmat(3, 3, :cv32f) + s1 = CvScalar.new(0.1, 0.2, 0.3, 0.4) + m2 = create_cvmat(3, 3, :cv32f) { s1 } + + # CvMat / CvMat + m3 = m1.div(m2) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3, 0.001) { |j, i, c| + n = c + 1 + CvScalar.new(n / 0.1, n / 0.2, n / 0.3, n / 0.4) + } + + # scale * CvMat / CvMat + scale = 2.5 + m3 = m1.div(m2, scale) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3, 0.001) { |j, i, c| + n = (c + 1) * scale + CvScalar.new(n / 0.1, n / 0.2, n / 0.3, n / 0.4) + } + + # CvMat / CvScalar + scale = 2.5 + m3 = m1.div(s1) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3, 0.001) { |j, i, c| + n = c + 1 + CvScalar.new(n / 0.1, n / 0.2, n / 0.3, n / 0.4) + } + + # scale * CvMat / CvScalar + m3 = m1.div(s1, scale) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3, 0.001) { |j, i, c| + n = (c + 1) * scale + CvScalar.new(n / 0.1, n / 0.2, n / 0.3, n / 0.4) + } + + # Alias + m3 = m1 / m2 + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3, 0.001) { |j, i, c| + n = c + 1 + CvScalar.new(n / 0.1, n / 0.2, n / 0.3, n / 0.4) + } + + assert_raise(TypeError) { + m1.div(DUMMY_OBJ) + } + assert_raise(TypeError) { + m1.div(m2, DUMMY_OBJ) + } + end + + def test_add_weighted + m1 = create_cvmat(3, 2, :cv8u) { |j, i, c| c + 1 } + m2 = create_cvmat(3, 2, :cv8u) { |j, i, c| (c + 1) * 10 } + a = 2.0 + b = 0.1 + g = 100 + m3 = CvMat.add_weighted(m1, a, m2, b, g) + assert_equal(m1.class, m3.class) + assert_equal(m1.rows, m3.rows) + assert_equal(m1.cols, m3.cols) + assert_equal(m1.depth, m3.depth) + assert_equal(m1.channel, m3.channel) + + m1.rows.times { |j| + m1.cols.times { |i| + expected = m1[j, i][0] * a + m2[j, i][0] * b + g + assert_equal(expected, m3[j, i][0]) + } + } + + assert_raise(TypeError) { + CvMat.add_weighted(DUMMY_OBJ, a, m2, b, g) + } + assert_raise(TypeError) { + CvMat.add_weighted(m1, DUMMY_OBJ, m2, b, g) + } + assert_raise(TypeError) { + CvMat.add_weighted(m1, a, DUMMY_OBJ, b, g) + } + assert_raise(TypeError) { + CvMat.add_weighted(m1, a, m2, DUMMY_OBJ, g) + } + assert_raise(TypeError) { + CvMat.add_weighted(m1, a, m2, b, DUMMY_OBJ) + } + end + + def test_and + m1 = create_cvmat(6, 4) + s1 = CvScalar.new(1, 2, 3, 4) + m2 = create_cvmat(6, 4) { s1 } + mask = create_cvmat(6, 4, :cv8u, 1) { |j, i, c| + s = (i < 3 and j < 2) ? 1 : 0 + CvScalar.new(s) + } + + # CvMat & CvMat + m3 = m1.and(m2) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3) { |j, i, c| + n = c + 1 + CvScalar.new(n & 1, n & 2, n & 3, n & 4) + } + + # CvMat & CvMat with mask + m3 = m1.and(m2, mask) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3) { |j, i, c| + n = c + 1 + if i < 3 and j < 2 + CvScalar.new(n & 1, n & 2, n & 3, n & 4) + else + CvScalar.new(n, n, n, n) + end + } + + # CvMat & CvScalar + m3 = m1.and(s1) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3) { |j, i, c| + n = c + 1 + CvScalar.new(n & 1, n & 2, n & 3, n & 4) + } + + # CvMat & CvScalar with mask + m3 = m1.and(s1, mask) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3) { |j, i, c| + n = c + 1 + if i < 3 and j < 2 + CvScalar.new(n & 1, n & 2, n & 3, n & 4) + else + CvScalar.new(n, n, n, n) + end + } + + # Alias + m3 = m1 & m2 + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3) { |j, i, c| + n = c + 1 + CvScalar.new(n & 1, n & 2, n & 3, n & 4) + } + + m3 = m1 & s1 + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3) { |j, i, c| + n = c + 1 + CvScalar.new(n & 1, n & 2, n & 3, n & 4) + } + + assert_raise(TypeError) { + m1.and(DUMMY_OBJ) + } + assert_raise(TypeError) { + m1.and(m2, DUMMY_OBJ) + } + end + + def test_or + m1 = create_cvmat(6, 4) + s1 = CvScalar.new(1, 2, 3, 4) + m2 = create_cvmat(6, 4) { s1 } + mask = create_cvmat(6, 4, :cv8u, 1) { |j, i, c| + s = (i < 3 and j < 2) ? 1 : 0 + CvScalar.new(s) + } + + # CvMat | CvMat + m3 = m1.or(m2) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3) { |j, i, c| + n = c + 1 + CvScalar.new(n | 1, n | 2, n | 3, n | 4) + } + + # CvMat | CvMat with mask + m3 = m1.or(m2, mask) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3) { |j, i, c| + n = c + 1 + if i < 3 and j < 2 + CvScalar.new(n | 1, n | 2, n | 3, n | 4) + else + CvScalar.new(n, n, n, n) + end + } + + # CvMat | CvScalar + m3 = m1.or(s1) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3) { |j, i, c| + n = c + 1 + CvScalar.new(n | 1, n | 2, n | 3, n | 4) + } + + # CvMat | CvScalar with mask + m3 = m1.or(s1, mask) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3) { |j, i, c| + n = c + 1 + if i < 3 and j < 2 + CvScalar.new(n | 1, n | 2, n | 3, n | 4) + else + CvScalar.new(n, n, n, n) + end + } + + # Alias + m3 = m1 | m2 + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3) { |j, i, c| + n = c + 1 + CvScalar.new(n | 1, n | 2, n | 3, n | 4) + } + + m3 = m1 | s1 + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3) { |j, i, c| + n = c + 1 + CvScalar.new(n | 1, n | 2, n | 3, n | 4) + } + + assert_raise(TypeError) { + m1.or(DUMMY_OBJ) + } + assert_raise(TypeError) { + m1.or(m2, DUMMY_OBJ) + } + end + + def test_xor + m1 = create_cvmat(6, 4) + s1 = CvScalar.new(1, 2, 3, 4) + m2 = create_cvmat(6, 4) { s1 } + mask = create_cvmat(6, 4, :cv8u, 1) { |j, i, c| + s = (i < 3 and j < 2) ? 1 : 0 + CvScalar.new(s) + } + + # CvMat ^ CvMat + m3 = m1.xor(m2) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3) { |j, i, c| + n = c + 1 + CvScalar.new(n ^ 1, n ^ 2, n ^ 3, n ^ 4) + } + + # CvMat ^ CvMat with mask + m3 = m1.xor(m2, mask) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3) { |j, i, c| + n = c + 1 + if i < 3 and j < 2 + CvScalar.new(n ^ 1, n ^ 2, n ^ 3, n ^ 4) + else + CvScalar.new(n, n, n, n) + end + } + + # CvMat ^ CvScalar + m3 = m1.xor(s1) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3) { |j, i, c| + n = c + 1 + CvScalar.new(n ^ 1, n ^ 2, n ^ 3, n ^ 4) + } + + # CvMat ^ CvScalar with mask + m3 = m1.xor(s1, mask) + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3) { |j, i, c| + n = c + 1 + if i < 3 and j < 2 + CvScalar.new(n ^ 1, n ^ 2, n ^ 3, n ^ 4) + else + CvScalar.new(n, n, n, n) + end + } + + # Alias + m3 = m1 ^ m2 + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3) { |j, i, c| + n = c + 1 + CvScalar.new(n ^ 1, n ^ 2, n ^ 3, n ^ 4) + } + + m3 = m1 ^ s1 + assert_equal(m1.height, m3.height) + assert_equal(m1.width, m3.width) + assert_each_cvscalar(m3) { |j, i, c| + n = c + 1 + CvScalar.new(n ^ 1, n ^ 2, n ^ 3, n ^ 4) + } + + assert_raise(TypeError) { + m1.xor(DUMMY_OBJ) + } + assert_raise(TypeError) { + m1.xor(m2, DUMMY_OBJ) + } + end + + def test_not + m1 = create_cvmat(6, 4, :cv8s) + m2 = m1.not; + m3 = m1.clone + m3.not! + [m2, m3].each { |m| + assert_equal(m1.height, m.height) + assert_equal(m1.width, m.width) + assert_each_cvscalar(m) { |j, i, c| + n = c + 1 + CvScalar.new(~n, ~n, ~n, ~n) + } + } + end + + def test_eq + m1 = create_cvmat(6, 4, :cv8u, 1) { |j, i, c| + n = (c.even?) ? 10 : c + CvScalar.new(n, 0, 0, 0) + } + m2 = create_cvmat(6, 4, :cv8u, 1) { |j, i, c| + CvScalar.new(10, 0, 0, 0) + } + s1 = CvScalar.new(10, 0, 0, 0) + m3 = m1.eq(m2) + m4 = m1.eq(s1) + m5 = m1.eq(10) + + [m3, m4, m5].each { |m| + assert_equal(m1.height, m.height) + assert_equal(m1.width, m.width) + assert_each_cvscalar(m) { |j, i, c| + n = (c.even?) ? 0xff : 0 + CvScalar.new(n, 0, 0, 0) + } + } + + assert_raise(TypeError) { + m1.eq(DUMMY_OBJ) + } + end + + def test_gt + m1 = create_cvmat(6, 4, :cv8u, 1) { |j, i, c| + CvScalar.new(c, 0, 0, 0) + } + m2 = create_cvmat(6, 4, :cv8u, 1) { |j, i, c| + CvScalar.new(10, 0, 0, 0) + } + s1 = CvScalar.new(10, 0, 0, 0) + m3 = m1.gt(m2) + m4 = m1.gt(s1) + m5 = m1.gt(10) + + [m3, m4, m5].each { |m| + assert_equal(m1.height, m.height) + assert_equal(m1.width, m.width) + assert_each_cvscalar(m) { |j, i, c| + n = (c > 10) ? 0xff : 0 + CvScalar.new(n, 0, 0, 0) + } + } + + assert_raise(TypeError) { + m1.gt(DUMMY_OBJ) + } + end + + def test_ge + m1 = create_cvmat(6, 4, :cv8u, 1) { |j, i, c| + CvScalar.new(c, 0, 0, 0) + } + m2 = create_cvmat(6, 4, :cv8u, 1) { |j, i, c| + CvScalar.new(10, 0, 0, 0) + } + s1 = CvScalar.new(10, 0, 0, 0) + m3 = m1.ge(m2) + m4 = m1.ge(s1) + m5 = m1.ge(10) + + [m3, m4, m5].each { |m| + assert_equal(m1.height, m.height) + assert_equal(m1.width, m.width) + assert_each_cvscalar(m) { |j, i, c| + n = (c >= 10) ? 0xff : 0 + CvScalar.new(n, 0, 0, 0) + } + } + + assert_raise(TypeError) { + m1.ge(DUMMY_OBJ) + } + end + + def test_lt + m1 = create_cvmat(6, 4, :cv8u, 1) { |j, i, c| + CvScalar.new(c, 0, 0, 0) + } + m2 = create_cvmat(6, 4, :cv8u, 1) { |j, i, c| + CvScalar.new(10, 0, 0, 0) + } + s1 = CvScalar.new(10, 0, 0, 0) + m3 = m1.lt(m2) + m4 = m1.lt(s1) + m5 = m1.lt(10) + + [m3, m4, m5].each { |m| + assert_equal(m1.height, m.height) + assert_equal(m1.width, m.width) + assert_each_cvscalar(m) { |j, i, c| + n = (c < 10) ? 0xff : 0 + CvScalar.new(n, 0, 0, 0) + } + } + + assert_raise(TypeError) { + m1.lt(DUMMY_OBJ) + } + end + + def test_le + m1 = create_cvmat(6, 4, :cv8u, 1) { |j, i, c| + CvScalar.new(c, 0, 0, 0) + } + m2 = create_cvmat(6, 4, :cv8u, 1) { |j, i, c| + CvScalar.new(10, 0, 0, 0) + } + s1 = CvScalar.new(10, 0, 0, 0) + m3 = m1.le(m2) + m4 = m1.le(s1) + m5 = m1.le(10) + + [m3, m4, m5].each { |m| + assert_equal(m1.height, m.height) + assert_equal(m1.width, m.width) + assert_each_cvscalar(m) { |j, i, c| + n = (c <= 10) ? 0xff : 0 + CvScalar.new(n, 0, 0, 0) + } + } + + assert_raise(TypeError) { + m1.le(DUMMY_OBJ) + } + end + + def test_in_range + lower, upper = 10, 20 + m0 = create_cvmat(6, 4, :cv8u, 1) { |j, i, c| + CvScalar.new(c + 5, 0, 0, 0) + } + m1 = create_cvmat(6, 4, :cv8u, 1) { |j, i, c| + CvScalar.new(lower, 0, 0, 0) + } + m2 = create_cvmat(6, 4, :cv8u, 1) { |j, i, c| + CvScalar.new(upper, 0, 0, 0) + } + s1 = CvScalar.new(lower, 0, 0, 0) + s2 = CvScalar.new(upper, 0, 0, 0) + + m3 = m0.in_range(m1, m2) + m4 = m0.in_range(s1, s2) + m5 = m0.in_range(lower, upper) + + [m3, m4, m5].each { |m| + assert_equal(m0.height, m.height) + assert_equal(m0.width, m.width) + assert_each_cvscalar(m) { |j, i, c| + val = m0[j, i][0] + n = ((lower..upper).include? val) ? 0xff : 0 + CvScalar.new(n, 0, 0, 0) + } + } + + assert_raise(TypeError) { + m0.in_range(DUMMY_OBJ, m2) + } + assert_raise(TypeError) { + m0.in_range(m1, DUMMY_OBJ) + } + end + + def test_abs_diff + m0 = create_cvmat(6, 4, :cv32f, 4) { |j, i, c| + CvScalar.new(-10 + 10.5, 20 + 10.5, -30 + 10.5, 40 - 10.5) + } + m1 = create_cvmat(6, 4, :cv32f, 4) { |j, i, c| + CvScalar.new(c + 10.5, c - 10.5, c + 10.5, c - 10.5) + } + m2 = create_cvmat(6, 4, :cv32f, 4) { |j, i, c| + CvScalar.new(c, c, c, c) + } + + s1 = CvScalar.new(-10, 20, -30, 40) + m3 = m1.abs_diff(m2) + m4 = m0.abs_diff(s1) + + [m3, m4].each { |m| + assert_equal(m1.width, m.width) + assert_equal(m1.height, m.height) + assert_each_cvscalar(m, 0.001) { + CvScalar.new(10.5, 10.5, 10.5, 10.5) + } + } + + assert_raise(TypeError) { + m0.abs_diff(DUMMY_OBJ) + } + end + + def test_normalize + mat = create_cvmat(2, 2, :cv32f, 1) { |j, i, c| + CvScalar.new(c, 0, 0, 0) + } + + m = mat.normalize + expected = [0.0, 0.267, 0.534, 0.801] + expected.each_with_index { |x, i| + assert_in_delta(x, m[i][0], 0.001) + } + + minf = mat.normalize(1, 0, CV_NORM_INF) + expected = [0.0, 0.333, 0.666, 1.0] + expected.each_with_index { |x, i| + assert_in_delta(x, minf[i][0], 0.001) + } + + ml1 = mat.normalize(1, 0, CV_NORM_L1) + expected = [0.0, 0.166, 0.333, 0.5] + expected.each_with_index { |x, i| + assert_in_delta(x, ml1[i][0], 0.001) + } + + ml2 = mat.normalize(1, 0, CV_NORM_L2) + expected = [0.0, 0.267, 0.534, 0.801] + expected.each_with_index { |x, i| + assert_in_delta(x, ml2[i][0], 0.001) + } + + mminmax = mat.normalize(10, 5, CV_NORM_MINMAX) + expected = [5.0, 6.666, 8.333, 10.0] + expected.each_with_index { |x, i| + assert_in_delta(x, mminmax[i][0], 0.001) + } + + minf = mat.normalize(1, 0, CV_NORM_INF, CV_32FC3) + expected = [0.0, 0.333, 0.666, 1.0] + expected.each_with_index { |x, i| + assert_in_delta(x, minf[i][0], 0.001) + } + + mask = mat.to_8u.zero + mask[0, 0] = CvScalar.new(255, 0, 0) + mask[1, 0] = CvScalar.new(255, 0, 0) + minf = mat.normalize(1, 0, CV_NORM_INF, -1, mask) + expected = [0.0, 0.0, 1.0, 0.0] + expected.each_with_index { |x, i| + assert_in_delta(x, minf[i][0], 0.001) + } + + assert_raise(TypeError) { + mat.normalize(DUMMY_OBJ, 0, CV_NORM_INF) + } + assert_raise(TypeError) { + mat.normalize(1, DUMMY_OBJ, CV_NORM_INF) + } + assert_raise(TypeError) { + mat.normalize(1, 0, DUMMY_OBJ) + } + assert_raise(TypeError) { + mat.normalize(1, 0, CV_NORM_INF, DUMMY_OBJ) + } + end + + def test_count_non_zero + m0 = create_cvmat(6, 4, :cv32f, 1) { |j, i, c| + n = 0 + n = 1 if i == 0 + CvScalar.new(n, 0, 0, 0) + } + assert_equal(6, m0.count_non_zero) + end + + def test_sum + m0 = create_cvmat(6, 4, :cv32f, 1) { |j, i, c| + CvScalar.new(c, c, c, c) + } + assert_cvscalar_equal(CvScalar.new(276, 0, 0, 0), m0.sum) + + m0 = create_cvmat(6, 4, :cv32f, 1) { |j, i, c| + CvScalar.new(-c) + } + assert_cvscalar_equal(CvScalar.new(-276, 0, 0, 0), m0.sum) + end + + def test_avg_sdv + m0 = create_cvmat(6, 4, :cv32f, 4) { |j, i, c| + CvScalar.new(c * 0.1, -c * 0.1, c, -c) + } + # CvMat#avg + assert_in_delta(CvScalar.new(1.15, -1.15, 11.5, -11.5), m0.avg, 0.001) + # CvMat#sdv + assert_in_delta(CvScalar.new(0.69221, 0.69221, 6.9221, 6.9221), m0.sdv, 0.001) + # CvMat#avg_sdv + avg, sdv = m0.avg_sdv + assert_in_delta(CvScalar.new(1.15, -1.15, 11.5, -11.5), avg, 0.001) + assert_in_delta(CvScalar.new(0.69221, 0.69221, 6.9221, 6.9221), sdv, 0.001) + + mask = create_cvmat(6, 4, :cv8u, 1) { |j, i, c| + n = (i == j) ? 1 : 0 + CvScalar.new(n) + } + # CvMat#avg + assert_in_delta(CvScalar.new(0.75, -0.75, 7.5, -7.5), m0.avg(mask), 0.001) + # CvMat#sdv + assert_in_delta(CvScalar.new(0.55901, 0.55901, 5.5901, 5.5901), m0.sdv(mask), 0.001) + # CvMat#avg_sdv + avg, sdv = m0.avg_sdv(mask) + assert_in_delta(CvScalar.new(0.75, -0.75, 7.5, -7.5), avg, 0.001) + assert_in_delta(CvScalar.new(0.55901, 0.55901, 5.5901, 5.5901), sdv, 0.001) + + assert_raise(TypeError) { + m0.avg(DUMMY_OBJ) + } + assert_raise(TypeError) { + m0.sdv(DUMMY_OBJ) + } + assert_raise(TypeError) { + m0.avg_sdv(DUMMY_OBJ) + } + end + + def test_min_max_loc + m0 = create_cvmat(6, 4, :cv32f, 1) { |j, i, c| + CvScalar.new(c * 0.5) + } + m0[2, 3] = CvScalar.new(100.5) # Max + m0[5, 1] = CvScalar.new(-100.5) # Min + + min_val, max_val, min_loc, max_loc = m0.min_max_loc + assert_equal(-100.5, min_val) + assert_equal(5, min_loc.y) + assert_equal(1, min_loc.x) + assert_equal(100.5, max_val) + assert_equal(2, max_loc.y) + assert_equal(3, max_loc.x) + + assert_raise(TypeError) { + m0.min_max_loc(DUMMY_OBJ) + } + end + + def test_norm + src1 = CvMat.new(3, 3, :cv32f, 1).set_data([1, 2, 3, 4, 5, 6, 7, 8, 9]) + src2 = CvMat.new(3, 3, :cv32f, 1).set_data([2, 3, 4, 5, 6, 7, 8, 9, 1]) + mask = CvMat.new(3, 3, :cv8u, 1).set_data([1, 1, 0, 1, 1, 0, 0, 0, 0]) + + assert_in_delta(CvMat.norm(src1), 16.88, 0.01) + + assert_in_delta(CvMat.norm(src1, nil, CV_NORM_L1), 45.0, 0.01) + assert_in_delta(CvMat.norm(src1, nil, CV_NORM_L2), 16.88, 0.01) + assert_in_delta(CvMat.norm(src1, nil, CV_NORM_INF), 9.0, 0.01) + + assert_in_delta(CvMat.norm(src1, src2, CV_NORM_L1), 16.0, 0.01) + assert_in_delta(CvMat.norm(src1, src2, CV_NORM_L2), 8.49, 0.01) + assert_in_delta(CvMat.norm(src1, src2, CV_NORM_INF), 8.0, 0.01) + + assert_in_delta(CvMat.norm(src1, src2, CV_NORM_L1, mask), 4.0, 0.01) + assert_in_delta(CvMat.norm(src1, src2, CV_NORM_L2, mask), 2.0, 0.01) + assert_in_delta(CvMat.norm(src1, src2, CV_NORM_INF, mask), 1.0, 0.01) + + assert_raise(TypeError) { + CvMat.norm(DUMMY_OBJ) + } + assert_raise(TypeError) { + CvMat.norm(src1, DUMMY_OBJ) + } + assert_raise(TypeError) { + CvMat.norm(src1, src2, DUMMY_OBJ) + } + assert_raise(TypeError) { + CvMat.norm(src1, src2, CV_NORM_L1, DUMMY_OBJ) + } + end + + def test_dot_product + m1 = create_cvmat(2, 2, :cv32f, 1) { |j, i, c| + CvScalar.new(c * 0.5) + } + m2 = create_cvmat(2, 2, :cv32f, 1) { |j, i, c| + CvScalar.new(c * 1.5) + } + assert_in_delta(10.5, m1.dot_product(m2), 0.001) + + m1 = create_cvmat(2, 2, :cv32f) { |j, i, c| + CvScalar.new(c * 0.5, c * 0.6, c * 0.7, c * 0.8) + } + m2 = create_cvmat(2, 2, :cv32f) { |j, i, c| + CvScalar.new(c * 1.5, c * 2.0, c * 2.5, c * 3.0) + } + assert_in_delta(85.39999, m1.dot_product(m2), 0.001) + + assert_raise(TypeError) { + m1.dot_product(DUMMY_OBJ) + } + end + + def test_cross_product + m1 = create_cvmat(1, 3, :cv32f, 1) { |j, i, c| + CvScalar.new(c * 0.5) + } + m2 = create_cvmat(1, 3, :cv32f, 1) { |j, i, c| + CvScalar.new(c + 1) + } + m3 = m1.cross_product(m2) + + assert_in_delta(CvScalar.new(-0.5), m3[0, 0], 0.001) + assert_in_delta(CvScalar.new(1), m3[0, 1], 0.001) + assert_in_delta(CvScalar.new(-0.5), m3[0, 2], 0.001) + + assert_raise(TypeError) { + m1.cross_product(DUMMY_OBJ) + } + end + + def test_transform + m0 = create_cvmat(5, 5, :cv32f, 3) { |j, i, c| + CvScalar.new(c * 0.5, c * 1.0, c * 1.5) + } + transmat = CvMat.new(3, 3, :cv32f, 1); + transmat[0, 0] = CvScalar.new(0.0) + transmat[1, 0] = CvScalar.new(0.0) + transmat[2, 0] = CvScalar.new(0.0) + + transmat[0, 1] = CvScalar.new(0.0) + transmat[1, 1] = CvScalar.new(0.0) + transmat[2, 1] = CvScalar.new(1.0) + + transmat[0, 2] = CvScalar.new(1.0) + transmat[1, 2] = CvScalar.new(0.0) + transmat[2, 2] = CvScalar.new(0.0) + + m1 = m0.transform(transmat) + assert_each_cvscalar(m1, 0.01) { |j, i, c| + CvScalar.new(c * 1.5, 0, c, 0) + } + + stf = CvMat.new(3, 1, :cv32f, 1) + stf[0, 0] = CvScalar.new(-10) + stf[1, 0] = CvScalar.new(0.0) + stf[2, 0] = CvScalar.new(5) + + m1 = m0.transform(transmat, stf) + assert_each_cvscalar(m1, 0.01) { |j, i, c| + CvScalar.new(c * 1.5 - 10, 0, c + 5, 0) + } + + assert_raise(TypeError) { + m0.transform(DUMMY_OBJ) + } + assert_raise(TypeError) { + m0.transform(transmat, DUMMY_OBJ) + } + end + + def test_perspective_transform + mat = CvMat.new(1, 1, :cv32f, 2) + mat[0] = CvScalar.new(2, 3) + transmat = CvMat.new(3, 3, :cv32f, 1).clear + mat.channel.times { |c| + transmat[c, c] = CvScalar.new(1.0) + } + transmat[2, 2] = CvScalar.new(0.5) + + m = mat.perspective_transform(transmat) + assert_equal(1, m.height) + assert_equal(1, m.width) + assert_equal(:cv32f, m.depth) + assert_equal(2, m.channel) + assert_in_delta(CvScalar.new(4, 6), m[0], 0.001); + + mat = CvMat.new(1, 1, :cv32f, 3) + mat[0] = CvScalar.new(2, 3, 4) + transmat = CvMat.new(4, 4, :cv32f, 1).clear + mat.channel.times { |c| + transmat[c, c] = CvScalar.new(1.0) + } + transmat[3, 3] = CvScalar.new(0.5) + + m = mat.perspective_transform(transmat) + assert_equal(1, m.height) + assert_equal(1, m.width) + assert_equal(:cv32f, m.depth) + assert_equal(3, m.channel) + assert_in_delta(CvScalar.new(4, 6, 8), m[0], 0.001); + + assert_raise(TypeError) { + mat.perspective_transform(DUMMY_OBJ) + } + assert_raise(CvStsAssert) { + mat.perspective_transform(CvMat.new(3, 3, :cv32f, 3)) + } + end + + def test_mul_transposed + mat0 = create_cvmat(2, 2, :cv32f, 1) { |j, i, c| + CvScalar.new((c + 1) * 2) + } + delta = create_cvmat(2, 2, :cv32f, 1) { |j, i, c| + CvScalar.new(c + 1) + } + + [mat0.mul_transposed, + mat0.mul_transposed(:delta => nil), + mat0.mul_transposed(:order => 0), + mat0.mul_transposed(:scale => 1.0)].each { |m| + expected = [20, 44, + 44, 100] + assert_equal(2, m.rows) + assert_equal(2, m.cols) + assert_equal(:cv32f, m.depth) + expected.each_with_index { |x, i| + assert_in_delta(x, m[i][0], 0.1) + } + } + + m = mat0.mul_transposed(:delta => delta) + expected = [5, 11, + 11, 25] + assert_equal(2, m.rows) + assert_equal(2, m.cols) + assert_equal(:cv32f, m.depth) + expected.each_with_index { |x, i| + assert_in_delta(x, m[i][0], 0.1) + } + + m = mat0.mul_transposed(:delta => delta, :order => 1, :scale => 2.0) + expected = [20, 28, + 28, 40] + assert_equal(2, m.rows) + assert_equal(2, m.cols) + assert_equal(:cv32f, m.depth) + expected.each_with_index { |x, i| + assert_in_delta(x, m[i][0], 0.1) + } + end + + def test_trace + m0 = create_cvmat(5, 5, :cv32f, 4) { |j, i, c| + CvScalar.new(c * 0.5, c * 1.0, c * 1.5, c * 2.0) + } + assert_in_delta(CvScalar.new(30, 60, 90, 120), m0.trace, 0.001) + end + + def test_transpose + m0 = create_cvmat(2, 3, :cv32f, 4) { |j, i, c| + CvScalar.new(c * 0.5, c * 1.0, c * 1.5, c * 2.0) + } + m1 = m0.transpose + m2 = m0.t + + [m1, m2].each { |m| + assert_equal(m0.rows, m.cols) + assert_equal(m0.cols, m.rows) + assert_each_cvscalar(m, 0.001) { |j, i, c| + m0[i, j] + } + } + end + + def test_det + elems = [2.5, 4.5, 2.0, + 3.0, 2.5, -0.5, + 1.0, 0.5, 1.5] + m0 = create_cvmat(3, 3, :cv32f, 1) { |j, i, c| + CvScalar.new(elems[c]) + } + assert_in_delta(-14.5, m0.det, 0.001) + end + + def test_invert + elems = [1, 2, 3, + 2, 6, 9, + 1, 4, 7] + m0 = create_cvmat(3, 3, :cv32f, 1) { |j, i, c| + CvScalar.new(elems[c]) + } + m1 = m0.invert + m2 = m0.invert(:lu) + m3 = m0.invert(:svd) + m4 = m0.invert(:svd_sym) + m5 = m0.invert(:svd_symmetric) + + expected = [3, -1, 0, -2.5, 2, -1.5, 1, -1, 1] + [m1, m2, m3].each { |m| + assert_equal(m0.width, m.width) + assert_equal(m0.height, m.height) + assert_each_cvscalar(m, 0.001) { |j, i, c| + CvScalar.new(expected[c]) + } + } + + expected = [3, -1, 0, -1.0, 0.15, 0.23, 0, 0.23, -0.15] + [m4, m5].each { |m| + assert_equal(m0.width, m.width) + assert_equal(m0.height, m.height) + assert_each_cvscalar(m, 0.1) { |j, i, c| + CvScalar.new(expected[c]) + } + } + + assert_raise(TypeError) { + m0.invert(DUMMY_OBJ) + } + end + + def test_solve + elems1 = [3, 4, 5, + 8, 9, 6, + 3, 5, 9] + elems2 = [3, + 4, + 5] + a = create_cvmat(3, 3, :cv32f, 1) { |j, i, c| + CvScalar.new(elems1[c]) + } + b = create_cvmat(3, 1, :cv32f, 1) { |j, i, c| + CvScalar.new(elems2[c]) + } + + m1 = CvMat.solve(a, b) + m2 = CvMat.solve(a, b, :lu) + m3 = CvMat.solve(a, b, :svd) + m4 = CvMat.solve(a, b, :svd_sym) + m5 = CvMat.solve(a, b, :svd_symmetric) + expected = [2, -2, 1] + [m1, m2, m3].each { |m| + assert_equal(b.width, m.width) + assert_equal(a.height, m.height) + assert_each_cvscalar(m, 0.001) { |j, i, c| + CvScalar.new(expected[c]) + } + } + + assert_raise(TypeError) { + CvMat.solve(DUMMY_OBJ, b) + } + assert_raise(TypeError) { + CvMat.solve(a, DUMMY_OBJ) + } + assert_raise(TypeError) { + CvMat.solve(a, b, DUMMY_OBJ) + } + end + + def test_svd + rows = 2 + cols = 3 + m0 = create_cvmat(rows, cols, :cv32f, 1) { |j, i, c| + CvScalar.new(c + 1) + } + + [m0.svd, m0.clone.svd(CV_SVD_MODIFY_A)].each { |w, u, v| + expected = [0.38632, -0.92237, + 0.92237, 0.38632] + assert_equal(rows, u.rows) + assert_equal(rows, u.cols) + expected.each_with_index { |x, i| + assert_in_delta(x, u[i][0], 0.0001) + } + + assert_equal(rows, w.rows) + assert_equal(cols, w.cols) + expected = [9.50803, 0, 0, + 0, 0.77287, 0] + expected.each_with_index { |x, i| + assert_in_delta(x, w[i][0], 0.0001) + } + + assert_equal(cols, v.rows) + assert_equal(rows, v.cols) + expected = [0.42867, 0.80596, + 0.56631, 0.11238, + 0.70395, -0.58120] + + expected.each_with_index { |x, i| + assert_in_delta(x, v[i][0], 0.0001) + } + } + + w, ut, v = m0.svd(CV_SVD_U_T) + expected = [0.38632, 0.92237, + -0.92237, 0.38632] + assert_equal(rows, ut.rows) + assert_equal(rows, ut.cols) + expected.each_with_index { |x, i| + assert_in_delta(x, ut[i][0], 0.0001) + } + + assert_equal(rows, w.rows) + assert_equal(cols, w.cols) + expected = [9.50803, 0, 0, + 0, 0.77287, 0] + expected.each_with_index { |x, i| + assert_in_delta(x, w[i][0], 0.0001) + } + + assert_equal(cols, v.rows) + assert_equal(rows, v.cols) + expected = [0.42867, 0.80596, + 0.56631, 0.11238, + 0.70395, -0.58120] + + expected.each_with_index { |x, i| + assert_in_delta(x, v[i][0], 0.0001) + } + + w, u, vt = m0.svd(CV_SVD_V_T) + expected = [0.38632, -0.92237, + 0.92237, 0.38632] + assert_equal(rows, u.rows) + assert_equal(rows, u.cols) + expected.each_with_index { |x, i| + assert_in_delta(x, u[i][0], 0.0001) + } + + assert_equal(rows, w.rows) + assert_equal(cols, w.cols) + expected = [9.50803, 0, 0, + 0, 0.77287, 0] + expected.each_with_index { |x, i| + assert_in_delta(x, w[i][0], 0.0001) + } + + assert_equal(rows, vt.rows) + assert_equal(cols, vt.cols) + expected = [0.42867, 0.56631, 0.70395, + 0.80596, 0.11238, -0.58120] + expected.each_with_index { |x, i| + assert_in_delta(x, vt[i][0], 0.0001) + } + end + + def test_eigenvv + elems = [6, -2, -3, 7] + m0 = create_cvmat(2, 2, :cv32f, 1) { |j, i, c| + CvScalar.new(elems[c]) + } + + v1 = m0.eigenvv + v2 = m0.eigenvv(10 ** -15) + v3 = m0.eigenvv(10 ** -15, 1, 1) + + [v1, v2].each { |vec, val| + assert_in_delta(-0.615, vec[0, 0][0], 0.01) + assert_in_delta(0.788, vec[0, 1][0], 0.01) + assert_in_delta(0.788, vec[1, 0][0], 0.01) + assert_in_delta(0.615, vec[1, 1][0], 0.01) + assert_in_delta(8.562, val[0][0], 0.01) + assert_in_delta(4.438, val[1][0], 0.01) + } + + vec3, val3 = v3 + assert_in_delta(-0.615, vec3[0, 0][0], 0.01) + assert_in_delta(0.788, vec3[0, 1][0], 0.01) + assert_in_delta(8.562, val3[0][0], 0.01) + + assert_raise(TypeError) { + m0.eigenvv(DUMMY_OBJ) + } + assert_raise(TypeError) { + m0.eigenvv(nil, DUMMY_OBJ) + } + assert_raise(TypeError) { + m0.eigenvv(nil, nil, DUMMY_OBJ) + } + end + + def test_find_homography + # Nx2 + src = CvMat.new(4, 2, :cv32f, 1) + dst = CvMat.new(4, 2, :cv32f, 1) + + # Nx3 (Homogeneous coordinates) + src2 = CvMat.new(4, 3, :cv32f, 1) + dst2 = CvMat.new(4, 3, :cv32f, 1) + + # Homography + # => + # (0, 0) => (50, 0) + # (255, 0) => (205, 0) + # (255, 255) => (255, 220) + # (0, 255) => (0, 275) + [[0, 0], [255, 0], [255, 255], [0, 255]].each_with_index { |coord, i| + src[i, 0] = coord[0] + src[i, 1] = coord[1] + + src2[i, 0] = coord[0] * 2 + src2[i, 1] = coord[1] * 2 + src2[i, 2] = 2 + } + [[50, 0], [205, 0], [255, 220], [0, 275]].each_with_index { |coord, i| + dst[i, 0] = coord[0] + dst[i, 1] = coord[1] + + dst2[i, 0] = coord[0] * 2 + dst2[i, 1] = coord[1] * 2 + dst2[i, 2] = 2 + } + + mat1 = CvMat.find_homography(src, dst) + mat2 = CvMat.find_homography(src, dst, :all) + mat3 = CvMat.find_homography(src, dst, :ransac) + mat4 = CvMat.find_homography(src, dst, :lmeds) + mat5, status5 = CvMat.find_homography(src, dst, :ransac, 5, true) + mat6, status6 = CvMat.find_homography(src, dst, :ransac, 5, true) + mat7 = CvMat.find_homography(src, dst, :ransac, 5, false) + mat8 = CvMat.find_homography(src, dst, :ransac, 5, nil) + mat9 = CvMat.find_homography(src, dst, :all, 5, true) + mat10, status10 = CvMat.find_homography(src2, dst2, :ransac, 5, true) + + [mat1, mat2, mat3, mat4, mat5, mat6, mat7, mat8, mat9, mat10].each { |mat| + assert_equal(3, mat.rows) + assert_equal(3, mat.cols) + assert_equal(:cv32f, mat.depth) + assert_equal(1, mat.channel) + [0.72430, -0.19608, 50.0, + 0.0, 0.62489, 0.0, + 0.00057, -0.00165, 1.0].each_with_index { |x, i| + assert_in_delta(x, mat[i][0], 0.0001) + } + } + + [status5, status6, status10].each { |status| + assert_equal(1, status.rows) + assert_equal(4, status.cols) + assert_equal(:cv8u, status.depth) + assert_equal(1, status.channel) + 4.times { |i| + assert_in_delta(1.0, status[i][0], 0.0001) + } + } + + assert_raise(TypeError) { + CvMat.find_homography(DUMMY_OBJ, dst, :ransac, 5, true) + } + assert_raise(TypeError) { + CvMat.find_homography(src, DUMMY_OBJ, :ransac, 5, true) + } + assert_raise(TypeError) { + CvMat.find_homography(src, dst, DUMMY_OBJ, 5, true) + } + assert_raise(TypeError) { + CvMat.find_homography(src, dst, :ransac, DUMMY_OBJ, true) + } + CvMat.find_homography(src, dst, :ransac, 5, DUMMY_OBJ) + end + + def test_find_fundamental_mat + points1 = [[488.362, 169.911], + [449.488, 174.44], + [408.565, 179.669], + [364.512, 184.56], + [491.483, 122.366], + [451.512, 126.56], + [409.502, 130.342], + [365.5, 134.0], + [494.335, 74.544], + [453.5, 76.5], + [411.646, 79.5901], + [366.498, 81.6577], + [453.5, 76.5], + [411.646, 79.5901], + [366.498, 81.6577]] + + points2 = [[526.605, 213.332], + [470.485, 207.632], + [417.5, 201.0], + [367.485, 195.632], + [530.673, 156.417], + [473.749, 151.39], + [419.503, 146.656], + [368.669, 142.565], + [534.632, 97.5152], + [475.84, 94.6777], + [421.16, 90.3223], + [368.5, 87.5], + [475.84, 94.6777], + [421.16, 90.3223], + [368.5, 87.5]] + + # 7 point + num_points = 7 + mat1 = CvMat.new(num_points, 2, :cv64f, 1) + mat2 = CvMat.new(num_points, 2, :cv64f, 1) + + points1[0...num_points].each_with_index { |pt, i| + mat1[i, 0] = CvScalar.new(pt[0]) + mat1[i, 1] = CvScalar.new(pt[1]) + } + points2[0...num_points].each_with_index { |pt, i| + mat2[i, 0] = CvScalar.new(pt[0]) + mat2[i, 1] = CvScalar.new(pt[1]) + } + f_mat1 = CvMat.find_fundamental_mat(mat1, mat2, CV_FM_7POINT) + f_mat2, status = CvMat.find_fundamental_mat(mat1, mat2, CV_FM_7POINT, :with_status => true) + + expected = [0.000009, 0.000029, -0.010343, + -0.000033, 0.000000, 0.014590, + 0.004415, -0.013420, 1.000000, + 0.000000, 0.000001, -0.000223, + -0.000001, 0.000036, -0.005309, + -0.000097, -0.006463, 1.000000, + 0.000002, 0.000005, -0.001621, + -0.000005, 0.000031, -0.002559, + 0.000527, -0.007424, 1.000000] + [f_mat1, f_mat2].each { |f_mat| + assert_equal(9, f_mat.rows) + assert_equal(3, f_mat.cols) + expected.each_with_index { |val, i| + assert_in_delta(val, f_mat[i][0], 1.0e-5) + } + } + assert_equal(num_points, status.cols) + num_points.times { |i| + assert_in_delta(1, status[i][0], 1.0e-5) + } + + # 8 point + num_points = 8 + mat1 = CvMat.new(num_points, 2, :cv64f, 1) + mat2 = CvMat.new(num_points, 2, :cv64f, 1) + + points1[0...num_points].each_with_index { |pt, i| + mat1[i, 0] = CvScalar.new(pt[0]) + mat1[i, 1] = CvScalar.new(pt[1]) + } + points2[0...num_points].each_with_index { |pt, i| + mat2[i, 0] = CvScalar.new(pt[0]) + mat2[i, 1] = CvScalar.new(pt[1]) + } + + f_mat1 = CvMat.find_fundamental_mat(mat1, mat2, CV_FM_8POINT) + f_mat2, status = CvMat.find_fundamental_mat(mat1, mat2, CV_FM_8POINT, :with_status => true) + + expected = [0.000001, 0.000004, -0.001127, + -0.000005, 0.000038, -0.003778, + 0.000819, -0.008325, 1.000000] + [f_mat1, f_mat2].each { |f_mat| + assert_equal(3, f_mat.rows) + assert_equal(3, f_mat.cols) + expected.each_with_index { |val, i| + assert_in_delta(val, f_mat[i][0], 1.0e-5) + } + } + assert_equal(num_points, status.cols) + num_points.times { |i| + assert_in_delta(1, status[i][0], 1.0e-5) + } + + # RANSAC default + num_points = points1.size + mat1 = CvMat.new(num_points, 2, :cv64f, 1) + mat2 = CvMat.new(num_points, 2, :cv64f, 1) + + points1[0...num_points].each_with_index { |pt, i| + mat1[i, 0] = CvScalar.new(pt[0]) + mat1[i, 1] = CvScalar.new(pt[1]) + } + points2[0...num_points].each_with_index { |pt, i| + mat2[i, 0] = CvScalar.new(pt[0]) + mat2[i, 1] = CvScalar.new(pt[1]) + } + + [CvMat.find_fundamental_mat(mat1, mat2, CV_FM_RANSAC, :with_status => false, + :maximum_distance => 1.0, :desirable_level => 0.99), + CvMat.find_fundamental_mat(mat1, mat2, CV_FM_RANSAC)].each { |f_mat| + assert_equal(3, f_mat.rows) + assert_equal(3, f_mat.cols) + expected = [0.000010, 0.000039, -0.011141, + -0.000045, -0.000001, 0.019631, + 0.004873, -0.017604, 1.000000] + expected.each_with_index { |val, i| + assert_in_delta(val, f_mat[i][0], 1.0e-5) + } + } + + # RANSAC with options + f_mat, status = CvMat.find_fundamental_mat(mat1, mat2, CV_FM_RANSAC, :with_status => true, + :maximum_distance => 2.0, :desirable_level => 0.8) + assert_equal(3, f_mat.rows) + assert_equal(3, f_mat.cols) + assert_equal(1, status.rows) + assert_equal(num_points, status.cols) + + expected_f_mat = [0.000009, 0.000030, -0.010692, + -0.000039, 0.000000, 0.020567, + 0.004779, -0.018064, 1.000000] + expected_f_mat.each_with_index { |val, i| + assert_in_delta(val, f_mat[i][0], 1.0e-5) + } + expected_status = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + expected_status.each_with_index { |val, i| + assert_in_delta(val, status[i][0], 1.0e-5) + } + + # LMedS default + num_points = 12 + mat1 = CvMat.new(num_points, 2, :cv64f, 1) + mat2 = CvMat.new(num_points, 2, :cv64f, 1) + + points1[0...num_points].each_with_index { |pt, i| + mat1[i, 0] = CvScalar.new(pt[0]) + mat1[i, 1] = CvScalar.new(pt[1]) + } + points2[0...num_points].each_with_index { |pt, i| + mat2[i, 0] = CvScalar.new(pt[0]) + mat2[i, 1] = CvScalar.new(pt[1]) + } + + [CvMat.find_fundamental_mat(mat1, mat2, CV_FM_LMEDS, :with_status => false, + :maximum_distance => 1.0, :desirable_level => 0.99), + CvMat.find_fundamental_mat(mat1, mat2, CV_FM_LMEDS)].each { |f_mat| + assert_equal(3, f_mat.rows) + assert_equal(3, f_mat.cols) + expected = [0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, + 0.0, 0.0, 1.0] + expected.each_with_index { |val, i| + assert_in_delta(val, f_mat[i][0], 0.1) + } + } + + # LMedS with options + f_mat, status = CvMat.find_fundamental_mat(mat1, mat2, CV_FM_LMEDS, :with_status => true, + :desirable_level => 0.8) + assert_equal(3, f_mat.rows) + assert_equal(3, f_mat.cols) + assert_equal(1, status.rows) + assert_equal(num_points, status.cols) + + expected_fmat = [0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, + 0.0, 0.0, 1.0] + expected_f_mat.each_with_index { |val, i| + assert_in_delta(val, f_mat[i][0], 0.1) + } + expected_status = [0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1] + expected_status.each_with_index { |val, i| + assert_equal(val, status[i][0].to_i) + } + + [CV_FM_7POINT, CV_FM_8POINT, CV_FM_RANSAC, CV_FM_LMEDS].each { |method| + assert_raise(TypeError) { + CvMat.find_fundamental_mat(DUMMY_OBJ, mat2, method, :with_status => true) + } + assert_raise(TypeError) { + CvMat.find_fundamental_mat(mat1, DUMMY_OBJ, method, :with_status => true) + } + assert_raise(TypeError) { + CvMat.find_fundamental_mat(mat1, mat2, method, DUMMY_OBJ) + } + } + assert_raise(TypeError) { + CvMat.find_fundamental_mat(mat1, mat2, DUMMY_OBJ, :with_status => true) + } + end + + def test_compute_correspond_epilines + test_func = lambda { |mat1, mat2, f_mat_arr, num_points| + f_mat = CvMat.new(3, 3, CV_64F, 1) + f_mat_arr.each_with_index { |a, i| + f_mat[i] = CvScalar.new(a) + } + + line = CvMat.compute_correspond_epilines(mat1, 1, f_mat) + assert_equal(num_points, line.rows) + assert_equal(3, line.cols) + + expected = [[-0.221257, -0.975215, 6.03758], + [0.359337, -0.933208, -3.61419], + [0.958304, -0.28575, -15.0573], + [0.73415, -0.678987, -10.4037], + [0.0208539, -0.999783, 2.11625], + [0.284451, -0.958691, -2.31993], + [0.624647, -0.780907, -8.35208], + [0.618494, -0.785789, -8.23888], + [0.766694, -0.642012, -11.0298], + [0.700293, -0.713855, -9.76109]] + + expected.size.times { |i| + assert_in_delta(expected[i][0], line[i, 0][0], 1.0e-3) + assert_in_delta(expected[i][1], line[i, 1][0], 1.0e-3) + assert_in_delta(expected[i][2], line[i, 2][0], 1.0e-3) + } + + assert_raise(ArgumentError) { + m = CvMat.new(10, 10, CV_32F, 1) + CvMat.compute_correspond_epilines(m, 1, f_mat) + } + } + + num_points = 10 + # input points are Nx2 matrix + points1 =[[17, 175], + [370, 24], + [192, 456], + [614, 202], + [116, 111], + [305, 32], + [249, 268], + [464, 157], + [259, 333], + [460, 224]] + + points2 = [[295, 28], + [584, 221], + [67, 172], + [400, 443], + [330, 9], + [480, 140], + [181, 140], + [350, 265], + [176, 193], + [333, 313]] + + mat1 = CvMat.new(num_points, 2, CV_64F, 1) + mat2 = CvMat.new(num_points, 2, CV_64F, 1) + points1.flatten.each_with_index { |pt, i| + mat1[i] = CvScalar.new(pt) + } + points2.flatten.each_with_index { |pt, i| + mat2[i] = CvScalar.new(pt) + } + + # pre computed f matrix from points1, points2 + # f_mat = CvMat.find_fundamental_mat(mat1, mat2, CV_FM_LMEDS) + f_mat_arr = [0.000266883, 0.000140277, -0.0445223, + -0.00012592, 0.000245543, -0.108868, + -0.00407942, -0.00291097, 1] + test_func.call(mat1, mat2, f_mat_arr, num_points) + + # input points are 2xN matrix + points1 = [[17, 370, 192, 614, 116, 305, 249, 464, 259, 460], + [175, 24, 456, 202, 111, 32, 268, 157, 333, 224]] + + points2 = [[295, 584, 67, 400, 330, 480, 181, 350, 176, 333], + [28, 221, 172, 443, 9, 140, 140, 265, 193, 313]] + + mat1 = CvMat.new(2, num_points, CV_64F, 1) + mat2 = CvMat.new(2, num_points, CV_64F, 1) + points1.flatten.each_with_index { |pt, i| + mat1[i] = CvScalar.new(pt) + } + points2.flatten.each_with_index { |pt, i| + mat2[i] = CvScalar.new(pt) + } + test_func.call(mat1, mat2, f_mat_arr, num_points) + + + f_mat = CvMat.new(3, 3, CV_64F, 1) + f_mat_arr.each_with_index { |a, i| + f_mat[i] = CvScalar.new(a) + } + assert_raise(TypeError) { + CvMat.compute_correspond_epilines(DUMMY_OBJ, 1, f_mat) + } + assert_raise(TypeError) { + CvMat.compute_correspond_epilines(mat1, DUMMY_OBJ, f_mat) + } + assert_raise(TypeError) { + CvMat.compute_correspond_epilines(mat1, 1, DUMMY_OBJ) + } + end + + def test_apply_color_map + mat = CvMat.new(64, 256, :cv8u, 1) + mat.cols.times { |c| + mat.rows.times { |r| + mat[r, c] = c + } + } + + results = [] + [COLORMAP_AUTUMN, COLORMAP_BONE, COLORMAP_JET, COLORMAP_WINTER, + COLORMAP_RAINBOW, COLORMAP_OCEAN, COLORMAP_SUMMER, COLORMAP_SPRING, + COLORMAP_COOL, COLORMAP_HSV, COLORMAP_PINK, COLORMAP_HOT].each { |colormap| + cmap = mat.apply_color_map(colormap) + assert_equal(CvMat, cmap.class) + assert_equal(mat.rows, cmap.rows) + assert_equal(mat.cols, cmap.cols) + results << cmap + } + + assert_raise(TypeError) { + mat.apply_color_map(DUMMY_OBJ) + } + + # Uncomment the following line to show the result + # snap *results + end + + def test_subspace_project + w = CvMat.new(10, 20, :cv32f, 1) + mean = CvMat.new(w.rows, 1, :cv32f, 1) + mat = CvMat.new(w.cols, w.rows, :cv32f, 1) + result = mat.subspace_project(w, mean) + + assert_equal(CvMat, result.class) + assert_equal(w.cols, result.rows) + assert_equal(w.cols, result.cols) + end + + def test_subspace_reconstruct + w = CvMat.new(10, 20, :cv32f, 1) + mean = CvMat.new(w.rows, 1, :cv32f, 1) + mat = CvMat.new(w.cols, w.cols, :cv32f, 1) + result = mat.subspace_reconstruct(w, mean) + + assert_equal(CvMat, result.class) + assert_equal(w.cols, result.rows) + assert_equal(w.rows, result.cols) + end +end + diff --git a/test/test_cvmat_drawing.rb b/test/test_cvmat_drawing.rb new file mode 100755 index 00000000..d54332c2 --- /dev/null +++ b/test/test_cvmat_drawing.rb @@ -0,0 +1,349 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for drawing functions of OpenCV::CvMat +class TestCvMat_drawing < OpenCVTestCase + def test_DRAWING_OPTION + CvMat::DRAWING_OPTION[:color].to_ary.each { |c| + assert_in_delta(0, c, 0.01) + } + assert_equal(1, CvMat::DRAWING_OPTION[:thickness]) + assert_equal(8, CvMat::DRAWING_OPTION[:line_type]) + assert_equal(0, CvMat::DRAWING_OPTION[:shift]) + end + + def test_FLOOD_FILL_OPTION + assert_equal(4, CvMat::FLOOD_FILL_OPTION[:connectivity]) + assert((not CvMat::FLOOD_FILL_OPTION[:fixed_range])) + assert((not CvMat::FLOOD_FILL_OPTION[:mask_only])) + end + + def test_line + m0 = create_cvmat(240, 320, :cv8u, 3) { CvColor::White } + m1 = m0.clone + m2 = m0.line(CvPoint.new(1, 0), CvPoint.new(m0.width - 1, m0.height - 1), + :color => CvColor::Red, :thickness => 3, :line_type => :aa) + m1.line!(CvPoint.new(1, 0), CvPoint.new(m0.width - 1, m0.height - 1), + :color => CvColor::Blue, :thickness => 1, :line_type => :aa) + + # Uncomment the following line to show the image + # snap(['Line: Blue, thickness = 1', m1], ['Line: Red, thickness = 3', m2]) + + assert_raise(TypeError) { + m0.line(DUMMY_OBJ, CvPoint.new(1, 0)) + } + assert_raise(TypeError) { + m0.line(CvPoint.new(1, 0), DUMMY_OBJ) + } + assert_raise(TypeError) { + m0.line(CvPoint.new(1, 0), CvPoint.new(1, 1), :color => DUMMY_OBJ) + } + # assert_raise(CvError) { + # m0.line(CvPoint.new(1, 0), CvPoint.new(1, 1), :thickness => DUMMY_OBJ) + # } + # m0.line(CvPoint.new(1, 0), CvPoint.new(1, 1), :line_type => DUMMY_OBJ) + end + + def test_rectangle + m0 = create_cvmat(240, 320, :cv8u, 3) { CvColor::White } + m1 = m0.clone + m2 = m0.rectangle(CvPoint.new(20, 20), CvPoint.new(m0.width - 20, m0.height - 20), + :color => CvColor::Red, :thickness => 3, :line_type => :aa) + m1.rectangle!(CvPoint.new(20, 20), CvPoint.new(m0.width - 20, m0.height - 20), + :color => CvColor::Blue, :thickness => 1, :line_type => :aa) + + # Uncomment the following line to show the image + # snap(['Rectangle: Blue, thickness = 1', m1], ['Rectangle: Red, thickness = 3', m2]) + + assert_raise(TypeError) { + m0.line(DUMMY_OBJ, CvPoint.new(1, 0)) + } + assert_raise(TypeError) { + m0.rectangle(CvPoint.new(1, 0), DUMMY_OBJ) + } + assert_raise(TypeError) { + m0.rectangle(CvPoint.new(1, 0), CvPoint.new(1, 1), :color => DUMMY_OBJ) + } + # assert_raise(CvError) { + # m0.rectangle(CvPoint.new(1, 0), CvPoint.new(1, 1), :thickness => DUMMY_OBJ) + # } + # m0.rectangle(CvPoint.new(1, 0), CvPoint.new(1, 1), :line_type => DUMMY_OBJ) + end + + def test_circle + m0 = create_cvmat(240, 320, :cv8u, 3) { CvColor::White } + m1 = m0.clone + m2 = m0.circle(CvPoint.new(m0.width / 2, m0.height / 2), 80, + :color => CvColor::Red, :thickness => 3, :line_type => :aa) + m1.circle!(CvPoint.new(m0.width / 2, m0.height / 2), 80, + :color => CvColor::Blue, :thickness => 1, :line_type => :aa) + + # Uncomment the following line to show the image + # snap(['Circle: Blue, thickness = 1', m1], ['Circle: Red, thickness = 3', m2]) + + assert_raise(TypeError) { + m0.circle(DUMMY_OBJ, 10) + } + assert_raise(TypeError) { + m0.circle(CvPoint.new(1, 0), DUMMY_OBJ) + } + assert_raise(TypeError) { + m0.circle(CvPoint.new(1, 0), 10, :color => DUMMY_OBJ) + } + # assert_raise(CvError) { + # m0.circle(CvPoint.new(1, 0), 10, :thickness => DUMMY_OBJ) + # } + m0.circle(CvPoint.new(1, 0), 10, :line_type => DUMMY_OBJ) + end + + def test_ellipse + m0 = create_cvmat(240, 320, :cv8u, 3) { CvColor::White } + m1 = m0.clone + m2 = m0.ellipse(CvPoint.new(m0.width / 2, m0.height / 2), CvSize.new(100, 60), 30, 0, 360, + :color => CvColor::Red, :thickness => 3, :line_type => :aa) + m1.ellipse!(CvPoint.new(m0.width / 2, m0.height / 2), CvSize.new(100, 60), 30, 0, 360, + :color => CvColor::Blue, :thickness => 1, :line_type => :aa) + + # Uncomment the following line to show the image + # snap(['Ellipse: Blue, thickness = 1', m1], ['Ellipse: Red, thickness = 3', m2]) + + assert_raise(TypeError) { + m1.ellipse(DUMMY_OBJ, CvSize.new(100, 60), 30, 0, 360) + } + assert_raise(TypeError) { + m1.ellipse(CvPoint.new(m0.width / 2, m0.height / 2), DUMMY_OBJ, 30, 0, 360) + } + assert_raise(TypeError) { + m1.ellipse(CvPoint.new(m0.width / 2, m0.height / 2), CvSize.new(100, 60), DUMMY_OBJ, 0, 360) + } + assert_raise(TypeError) { + m1.ellipse(CvPoint.new(m0.width / 2, m0.height / 2), CvSize.new(100, 60), 30, DUMMY_OBJ, 360) + } + assert_raise(TypeError) { + m1.ellipse(CvPoint.new(m0.width / 2, m0.height / 2), CvSize.new(100, 60), 30, 0, DUMMY_OBJ) + } + assert_raise(TypeError) { + m1.ellipse(CvPoint.new(m0.width / 2, m0.height / 2), CvSize.new(100, 60), 30, 0, 360, + :color => DUMMY_OBJ) + } + # assert_raise(CvError) { + # m1.ellipse(CvPoint.new(m0.width / 2, m0.height / 2), CvSize.new(100, 60), 30, 0, 360, + # :thickness => DUMMY_OBJ) + # } + m1.ellipse(CvPoint.new(m0.width / 2, m0.height / 2), CvSize.new(100, 60), 30, 0, 360, + :line_type => DUMMY_OBJ) + end + + def test_ellipse_box + m0 = create_cvmat(240, 320, :cv8u, 3) { CvColor::White } + box = CvBox2D.new(CvPoint2D32f.new(m0.width / 2, m0.height / 2), CvSize2D32f.new(120, 160), 30) + m1 = m0.clone + m2 = m0.ellipse_box(box, :color => CvColor::Red, :thickness => 3, :line_type => :aa) + m1.ellipse_box!(box, :color => CvColor::Blue, :thickness => 1, :line_type => :aa) + + # Uncomment the following line to show the image + # snap(['Ellipse box: Blue, thickness = 1', m1], ['Ellipse box: Red, thickness = 3', m2]) + + assert_raise(TypeError) { + m1.ellipse_box(DUMMY_OBJ) + } + assert_raise(TypeError) { + m1.ellipse_box(box, :color => DUMMY_OBJ) + } + # assert_raise(CvError) { + # m1.ellipse_box(box, :thickness => DUMMY_OBJ) + # } + m1.ellipse_box(box, :line_type => DUMMY_OBJ) + end + + def test_fill_poly + m0 = create_cvmat(240, 320, :cv8u, 3) { CvColor::White } + pt = [[CvPoint.new(10, 20), CvPoint.new(10, 150), CvPoint.new(100, 50)], + [CvPoint.new(200, 10), CvPoint.new(200, 200), CvPoint.new(170, 200)], + [CvPoint.new(30, 10), CvPoint.new(0, 0), CvPoint.new(90, 150)]] + + m1 = m0.clone + m2 = m0.fill_poly(pt, :color => CvColor::Red, :line_type => :aa) + m1.fill_poly!(pt, :color => CvColor::Blue, :line_type => :aa) + + # Uncomment the following line to view the image + # snap(['Fill poly: Blue', m1], ['Fill poly: Red', m2]) + + assert_raise(TypeError) { + m1.fill_poly(DUMMY_OBJ) + } + assert_raise(TypeError) { + m1.fill_poly([DUMMY_OBJ, DUMMY_OBJ]) + } + assert_raise(TypeError) { + m1.fill_poly(pt, :color => DUMMY_OBJ) + } + # assert_raise(CvError) { + # m1.fill_poly(pt, :thickness => DUMMY_OBJ) + # } + # m1.fill_poly(pt, :line_type => DUMMY_OBJ) + end + + def test_fill_convex_poly + m0 = create_cvmat(240, 320, :cv8u, 3) { CvColor::White } + pt = [CvPoint.new(10, 20), CvPoint.new(10, 150), CvPoint.new(100, 50)] + + m1 = m0.clone + m2 = m0.fill_convex_poly(pt, :color => CvColor::Red, :line_type => :aa) + m1.fill_convex_poly!(pt, :color => CvColor::Blue, :line_type => :aa) + + # Uncomment the following line to view the image + # snap(['Fill convex poly: Blue', m1], ['Fill convex poly: Red', m2]) + + + assert_raise(TypeError) { + m1.fill_convex_poly(DUMMY_OBJ) + } + assert_raise(TypeError) { + m1.fill_convex_poly([DUMMY_OBJ, DUMMY_OBJ]) + } + assert_raise(TypeError) { + m1.fill_convex_poly(pt, :color => DUMMY_OBJ) + } + # assert_raise(CvError) { + # m1.fill_convex_poly(pt, :thickness => DUMMY_OBJ) + # } + # m1.fill_convex_poly(pt, :line_type => DUMMY_OBJ) + end + + def test_poly_line + m0 = create_cvmat(240, 320, :cv8u, 3) { CvColor::White } + pt = [[CvPoint.new(10, 20), CvPoint.new(10, 150), CvPoint.new(100, 150), CvPoint.new(10, 20)], + [CvPoint.new(100, 200), CvPoint.new(200, 190), CvPoint.new(180, 50), CvPoint.new(100, 200)]] + + m1 = m0.clone + m2 = m0.poly_line(pt, :color => CvColor::Red, :thickness => 3, :line_type => :aa) + m1.poly_line!(pt, :color => CvColor::Blue, :thickness => 1, :line_type => :aa) + + # Uncomment the following line to view the image + # snap(['Fill poly line: Blue, thickness = 1', m1], ['Fill poly line: Red, thickness = 3', m2]) + + assert_raise(TypeError) { + m1.poly_line(DUMMY_OBJ) + } + assert_raise(TypeError) { + m1.poly_line([DUMMY_OBJ, DUMMY_OBJ]) + } + assert_raise(TypeError) { + m1.poly_line([[DUMMY_OBJ, DUMMY_OBJ], [DUMMY_OBJ, DUMMY_OBJ]]) + } + assert_raise(TypeError) { + m1.poly_line(pt, :color => DUMMY_OBJ) + } + # assert_raise(CvError) { + # m1.poly_line(pt, :thickness => DUMMY_OBJ) + # } + # m1.poly_line(pt, :line_type => DUMMY_OBJ) + end + + def test_draw_contours + mat0 = CvMat.load(FILENAME_CONTOURS, CV_LOAD_IMAGE_GRAYSCALE) + + mat0 = mat0.threshold(128, 255, CV_THRESH_BINARY) + contours = mat0.find_contours(:mode => CV_RETR_TREE, :method => CV_CHAIN_APPROX_SIMPLE) + dst0 = mat0.clone.clear + dst1 = mat0.clone.clear.GRAY2BGR + begin + dst0 = dst0.draw_contours!(contours, CvColor::Black, CvColor::White, -1) + dst1.draw_contours!(contours, CvColor::Red, CvColor::Blue, 2, + :thickness => -1, :line_type => :aa) + end while (contours = contours.h_next) + + [dst0, dst1].each { |dst| + assert_equal(mat0.class, dst.class) + assert_equal(mat0.rows, dst.rows) + assert_equal(mat0.cols, dst.cols) + assert_equal(mat0.depth, dst.depth) + } + + assert_raise(TypeError) { + dst0.draw_contours(DUMMY_OBJ, CvColor::Black, CvColor::White, -1) + } + assert_raise(TypeError) { + dst0.draw_contours(contours, DUMMY_OBJ, CvColor::White, -1) + } + assert_raise(TypeError) { + dst0.draw_contours(contours, CvColor::Black, DUMMY_OBJ, -1) + } + assert_raise(TypeError) { + dst0.draw_contours(contours, CvColor::Black, CvColor::White, DUMMY_OBJ) + } + assert_raise(TypeError) { + dst0.draw_contours(contours, CvColor::Black, CvColor::White, -1, :thickness => DUMMY_OBJ) + } + assert_raise(TypeError) { + dst0.draw_contours(contours, CvColor::Black, CvColor::White, -1, :line_type => DUMMY_OBJ) + } + + # Uncomment the following line to show the results + # snap ['src', mat0], ['result0', dst0], ['result1', dst1] + end + + def test_draw_chessboard_corners + mat0 = CvMat.load(FILENAME_CHESSBOARD, 1) + mat1 = mat0.clone + pattern_size = CvSize.new(4, 4) + + gray = mat1.BGR2GRAY + corners, found = gray.find_chessboard_corners(pattern_size) + + mat2 = mat1.draw_chessboard_corners(pattern_size, corners, found) + mat1.draw_chessboard_corners!(pattern_size, corners, found) + [mat1, mat2].each { |dst| + assert_equal(mat0.class, dst.class) + assert_equal(mat0.rows, dst.rows) + assert_equal(mat0.cols, dst.cols) + assert_equal(mat0.depth, dst.depth) + } + + assert_raise(TypeError) { + mat1.draw_chessboard_corners(DUMMY_OBJ, corners, found) + } + assert_raise(TypeError) { + mat1.draw_chessboard_corners(pattern_size, DUMMY_OBJ, found) + } + assert_nothing_raised { + mat1.draw_chessboard_corners(pattern_size, corners, DUMMY_OBJ) + } + + # Uncomment the following line to show the results + # snap mat0, mat1, mat2 + end + + def test_put_text + m0 = create_cvmat(240, 320, :cv8u, 3) { CvColor::White } + m1 = m0.clone + m1.put_text!('test 1', CvPoint.new(60, 90), CvFont.new(:simplex), CvColor::Blue) + font = CvFont.new(:plain, :hscale => 5.0, :vscale => 4.5, + :shear => 1.0, :thickness => 3, :line_type => 5, :italic => true) + m2 = m0.put_text('test 2', CvPoint.new(30, 80), font, CvColor::Red) + + # Uncomment the following lines to view the image + # snap(['Put text: Blue, thickness = 1', m1], ['Put text: Red, thickness = 3', m2]) + + assert_raise(TypeError) { + m0.put_text(DUMMY_OBJ, CvPoint.new(60, 90), font) + } + assert_raise(TypeError) { + m0.put_text('test', DUMMY_OBJ, font) + } + assert_raise(TypeError) { + m0.put_text('test', CvPoint.new(60, 90), DUMMY_OBJ) + } + assert_raise(TypeError) { + m0.put_text('test', CvPoint.new(60, 90), font, DUMMY_OBJ) + } + end +end + + diff --git a/test/test_cvmat_dxt.rb b/test/test_cvmat_dxt.rb new file mode 100755 index 00000000..7246e8c6 --- /dev/null +++ b/test/test_cvmat_dxt.rb @@ -0,0 +1,150 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for dft and dct functions of OpenCV::CvMat +class TestCvMat_dxt < OpenCVTestCase + def test_dft_1D + n = 32 + w = 2 * Math::PI / n + + mat0 = create_cvmat(n, 1, :cv32f, 2) { |j, i, c| + s = Math.sin(c * w) + CvScalar.new(s, s) + } + + mat1 = mat0.dft(CV_DXT_FORWARD) + mat2 = mat0.dft(CV_DXT_FORWARD | CV_DXT_SCALE) + mat3 = mat0.dft(CV_DXT_FORWARD | CV_DXT_SCALE).dft(CV_DXT_INVERSE) + n.times { |j| + if j == 1 + assert_in_delta(n / 2, mat1[j, 0][0], 0.001) + assert_in_delta(-n / 2, mat1[j, 0][1], 0.001) + assert_in_delta(0.5, mat2[j, 0][0], 0.001) + assert_in_delta(-0.5, mat2[j, 0][1], 0.001) + elsif j == n - 1 + assert_in_delta(-n / 2, mat1[j, 0][0], 0.001) + assert_in_delta(n / 2, mat1[j, 0][1], 0.001) + assert_in_delta(-0.5, mat2[j, 0][0], 0.001) + assert_in_delta(0.5, mat2[j, 0][1], 0.001) + else + assert_in_delta(0, mat1[j, 0][0], 0.001) + assert_in_delta(0, mat1[j, 0][1], 0.001) + assert_in_delta(0, mat2[j, 0][0], 0.001) + assert_in_delta(0, mat2[j, 0][1], 0.001) + end + assert_in_delta(mat0[j, 0][0], mat3[j, 0][0], 0.001) + assert_in_delta(mat0[j, 0][1], mat3[j, 0][1], 0.001) + } + + assert_raise(TypeError) { + mat0.dft(DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.dft(CV_DXT_FORWARD, DUMMY_OBJ) + } + end + + def test_dft_2D + n = 32 + w = 2 * Math::PI / n + c = 0 + mat0 = CvMat.new(n, n, :cv32f, 2) + n.times { |j| + s = Math.sin(c * w) + n.times { |i| + mat0[j, i] = CvScalar.new(s, s) + } + c += 1 + } + + mat1 = mat0.dft(CV_DXT_FORWARD) + mat2 = mat0.dft(CV_DXT_FORWARD | CV_DXT_SCALE) + mat3 = mat0.dft(CV_DXT_FORWARD | CV_DXT_SCALE).dft(CV_DXT_INVERSE) + n.times { |j| + n.times { |i| + if i == 0 and j == 1 + assert_in_delta(n * n / 2, mat1[j, i][0], 0.001) + assert_in_delta(-n * n / 2, mat1[j, i][1], 0.001) + assert_in_delta(0.5, mat2[j, i][0], 0.001) + assert_in_delta(-0.5, mat2[j, i][1], 0.001) + elsif i == 0 and j == n - 1 + assert_in_delta(-n * n / 2, mat1[j, i][0], 0.001) + assert_in_delta(n * n / 2, mat1[j, i][1], 0.001) + assert_in_delta(-0.5, mat2[j, i][0], 0.001) + assert_in_delta(0.5, mat2[j, i][1], 0.001) + else + assert_in_delta(0, mat1[j, i][0], 0.001) + assert_in_delta(0, mat1[j, i][1], 0.001) + assert_in_delta(0, mat2[j, i][0], 0.001) + assert_in_delta(0, mat2[j, i][1], 0.001) + end + assert_in_delta(mat0[j, 0][0], mat3[j, i][0], 0.001) + assert_in_delta(mat0[j, 0][1], mat3[j, i][1], 0.001) + } + } + end + + def test_dct_1D + n = 8 + w = 2 * Math::PI / n + + mat0 = create_cvmat(n, 1, :cv32f, 1) { |j, i, c| + s = Math.sin(c * w) + CvScalar.new(s) + } + + mat1 = mat0.dct(CV_DXT_FORWARD) + mat2 = mat0.dct(CV_DXT_FORWARD).dct(CV_DXT_INVERSE) + expected1 = [0, 1.599647, -0.765367, -0.906127, 0, -0.180240, 0, -0.042290] + n.times { |j| + assert_in_delta(expected1[j], mat1[j, 0][0], 0.001) + assert_in_delta(mat0[j, 0][0], mat2[j, 0][0], 0.001) + } + + assert_raise(TypeError) { + mat0.dct(DUMMY_OBJ) + } + end + + def test_dct_2D + n = 8 + w = 2 * Math::PI / n + c = 0 + mat0 = CvMat.new(n, n, :cv32f, 1) + n.times { |j| + s = Math.sin(c * w) + n.times { |i| + mat0[j, i] = CvScalar.new(s, s) + } + c += 1 + } + + mat1 = mat0.dct(CV_DXT_FORWARD) + mat2 = mat0.dct(CV_DXT_FORWARD).dct(CV_DXT_INVERSE) + n.times { |j| + n.times { |i| + if i == 0 and j == 1 + assert_in_delta(4.524486, mat1[j, i][0], 0.001) + elsif i == 0 and j == 2 + assert_in_delta(-2.164784, mat1[j, i][0], 0.001) + elsif i == 0 and j == 3 + assert_in_delta(-2.562915, mat1[j, i][0], 0.001) + elsif i == 0 and j == 5 + assert_in_delta(-0.509796, mat1[j, i][0], 0.001) + elsif i == 0 and j == 7 + assert_in_delta(-0.119615, mat1[j, i][0], 0.001) + else + assert_in_delta(0, mat1[j, i][0], 0.001) + end + assert_in_delta(mat0[j, i][0], mat2[j, i][0], 0.001) + } + } + end +end + + diff --git a/test/test_cvmat_imageprocessing.rb b/test/test_cvmat_imageprocessing.rb new file mode 100755 index 00000000..05a40195 --- /dev/null +++ b/test/test_cvmat_imageprocessing.rb @@ -0,0 +1,2085 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for image processing functions of OpenCV::CvMat +class TestCvMat_imageprocessing < OpenCVTestCase + FILENAME_LENA256x256 = File.expand_path(File.dirname(__FILE__)) + '/samples/lena-256x256.jpg' + FILENAME_LENA_INPAINT = File.expand_path(File.dirname(__FILE__)) + '/samples/lena-inpaint.jpg' + FILENAME_INPAINT_MASK = File.expand_path(File.dirname(__FILE__)) + '/samples/inpaint-mask.bmp' + FILENAME_LENA32x32 = File.expand_path(File.dirname(__FILE__)) + '/samples/lena-32x32.jpg' + FILENAME_LINES = File.expand_path(File.dirname(__FILE__)) + '/samples/lines.jpg' + FILENAME_LENA_EYES = File.expand_path(File.dirname(__FILE__)) + '/samples/lena-eyes.jpg' + FILENAME_STR_CV = File.expand_path(File.dirname(__FILE__)) + '/samples/str-cv.jpg' + FILENAME_STR_OV = File.expand_path(File.dirname(__FILE__)) + '/samples/str-ov.jpg' + FILENAME_STR_CV_ROTATED = File.expand_path(File.dirname(__FILE__)) + '/samples/str-cv-rotated.jpg' + + def test_sobel + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_GRAYSCALE) + + mat1 = mat0.sobel(1, 0).convert_scale_abs(:scale => 1, :shift => 0) + mat2 = mat0.sobel(0, 1).convert_scale_abs(:scale => 1, :shift => 0) + mat3 = mat0.sobel(1, 1).convert_scale_abs(:scale => 1, :shift => 0) + mat4 = mat0.sobel(1, 1, 3).convert_scale_abs(:scale => 1, :shift => 0) + mat5 = mat0.sobel(1, 1, 5).convert_scale_abs(:scale => 1, :shift => 0) + + assert_equal('30a26b7287fac75bb697bc7eef6bb53a', hash_img(mat1)) + assert_equal('b740afb13b556d55280fa785190ac902', hash_img(mat2)) + assert_equal('36c29ca64a599e0f5633f4f3948ed858', hash_img(mat3)) + assert_equal('36c29ca64a599e0f5633f4f3948ed858', hash_img(mat4)) + assert_equal('30b9e8fd64e7f86c50fb67d8703628e3', hash_img(mat5)) + + assert_equal(:cv16s, CvMat.new(16, 16, :cv8u, 1).sobel(1, 1).depth) + assert_equal(:cv32f, CvMat.new(16, 16, :cv32f, 1).sobel(1, 1).depth) + + (DEPTH.keys - [:cv8u, :cv32f]).each { |depth| + assert_raise(ArgumentError) { + CvMat.new(3, 3, depth).sobel(1, 1) + } + } + + # Uncomment the following lines to view the images + # snap(['original', mat0], ['sobel(1,0)', mat1], ['sobel(0,1)', mat2], + # ['sobel(1,1)', mat3], ['sobel(1,1,3)', mat4], ['sobel(1,1,5)', mat5]) + + assert_raise(TypeError) { + mat0.sobel(DUMMY_OBJ, 0) + } + assert_raise(TypeError) { + mat0.sobel(1, DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.sobel(1, 0, DUMMY_OBJ) + } + end + + def test_laplace + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_GRAYSCALE) + + mat1 = mat0.laplace.convert_scale_abs(:scale => 1, :shift => 0) + mat2 = mat0.laplace(3).convert_scale_abs(:scale => 1, :shift => 0) + mat3 = mat0.laplace(5).convert_scale_abs(:scale => 1, :shift => 0) + + assert_equal('824f8de75bfead5d83c4226f3948ce69', hash_img(mat1)) + assert_equal('824f8de75bfead5d83c4226f3948ce69', hash_img(mat2)) + assert_equal('23850bb8cfe9fd1b82cd73b7b4659369', hash_img(mat3)) + + assert_equal(:cv16s, CvMat.new(16, 16, :cv8u, 1).laplace.depth) + assert_equal(:cv32f, CvMat.new(16, 16, :cv32f, 1).laplace.depth) + + (DEPTH.keys - [:cv8u, :cv32f]).each { |depth| + assert_raise(ArgumentError) { + CvMat.new(3, 3, depth).laplace + } + } + + # Uncomment the following line to view the images + # snap(['original', mat0], ['laplace', mat1], ['laplace(3)', mat2], ['laplace(5)', mat3]) + + assert_raise(TypeError) { + mat0.laplace(DUMMY_OBJ) + } + end + + def test_canny + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_GRAYSCALE) + mat1 = mat0.canny(50, 200) + mat2 = mat0.canny(50, 200, 3) + mat3 = mat0.canny(50, 200, 5) + + assert_equal('ec3e88035bb98b5c5f1a08c8e07ab0a8', hash_img(mat1)) + assert_equal('ec3e88035bb98b5c5f1a08c8e07ab0a8', hash_img(mat2)) + assert_equal('1983a6d325d11eea3261462103b0dae1', hash_img(mat3)) + + # Uncomment the following line to view the images + # snap(['canny(50,200)', mat1], ['canny(50,200,3)', mat2], ['canny(50,200,5)', mat3]) + + assert_raise(TypeError) { + mat0.canny(DUMMY_OBJ, 200) + } + assert_raise(TypeError) { + mat0.canny(50, DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.canny(50, 200, DUMMY_OBJ) + } + end + + def test_pre_corner_detect + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_GRAYSCALE) + mat1 = mat0.pre_corner_detect + mat2 = mat0.pre_corner_detect(3) + mat3 = mat0.pre_corner_detect(5) + + assert_in_delta(0, count_threshold(mat1, 0.1), 30) + assert_in_delta(0, count_threshold(mat2, 0.1), 30) + assert_in_delta(380, count_threshold(mat3, 0.1), 30) + + # Uncomment the following lines to show the images + # snap(['original', mat0], ['pre_coner_detect', mat1], + # ['pre_coner_detect(3)', mat2], ['pre_coner_detect(5)', mat3]) + + assert_raise(TypeError) { + mat0.pre_corner_detect(DUMMY_OBJ) + } + end + + def test_corner_eigenvv + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_GRAYSCALE) + mat1 = mat0.corner_eigenvv(3) + mat2 = mat0.corner_eigenvv(3, 3) + + assert_raise(TypeError) { + mat0.corner_eigenvv(DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.corner_eigenvv(3, DUMMY_OBJ) + } + + flunk('FIXME: CvMat#corner_eigenvv is not tested yet.') + end + + def test_corner_min_eigen_val + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_GRAYSCALE) + mat1 = mat0.corner_min_eigen_val(3) + mat2 = mat0.corner_min_eigen_val(3, 3) + + assert_raise(TypeError) { + mat0.corner_min_eigen_val(DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.corner_min_eigen_val(3, DUMMY_OBJ) + } + + flunk('FIXME: CvMat#corner_min_eigen_val is not tested yet.') + end + + def test_corner_harris + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_GRAYSCALE) + mat1 = mat0.corner_harris(3) + mat2 = mat0.corner_harris(3, 3) + mat3 = mat0.corner_harris(3, 3, 0.04) + mat4 = mat0.corner_harris(3, 7, 0.01) + + [mat1, mat2, mat3].each { |mat| + assert_equal(mat0.rows, mat.rows) + assert_equal(mat0.cols, mat.cols) + assert_in_delta(0, count_threshold(mat, 10), 10) + } + assert_equal(mat0.rows, mat4.rows) + assert_equal(mat0.cols, mat4.cols) + assert_in_delta(90, count_threshold(mat4, 10), 10) + + # Uncomment the following lines to show the images + # snap(['original', mat0], ['corner_harris(3)', mat1], ['corner_harris(3,3)', mat2], + # ['corner_harris(3,3,0.04)', mat3], ['corner_harris(3,7,0.01)', mat4]) + + assert_raise(TypeError) { + mat0.corner_harris(DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.corner_harris(3, DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.corner_harris(3, 3, DUMMY_OBJ) + } + end + + def test_find_chessboard_corners + mat = CvMat.load(FILENAME_CHESSBOARD, CV_LOAD_IMAGE_GRAYSCALE) + pattern_size = CvSize.new(4, 4) + corners1, found1 = mat.find_chessboard_corners(pattern_size) + corners2, found2 = mat.find_chessboard_corners(pattern_size, CV_CALIB_CB_ADAPTIVE_THRESH) + corners3, found3 = mat.find_chessboard_corners(pattern_size, CV_CALIB_CB_NORMALIZE_IMAGE) + corners4, found4 = mat.find_chessboard_corners(pattern_size, CV_CALIB_CB_FILTER_QUADS) + corners5, found5 = mat.find_chessboard_corners(pattern_size, CV_CALIB_CB_FAST_CHECK) + + expected = [[39, 39], [79, 39], [119, 39], [159, 39], [39, 79], [79, 79], + [119, 79], [159, 78], [38, 119], [79, 119], [119, 119], [158, 118], + [39, 159], [79, 159], [119, 159], [159, 159]] + [corners1, corners2, corners3, corners4, corners5].each { |corners| + assert_equal(expected.size, corners.size) + expected.zip(corners).each { |e, a| + assert_in_delta(e[0], a.x, 3.0) + assert_in_delta(e[1], a.y, 3.0) + } + } + [found1, found2, found3, found4, found5].each { |found| + assert(found) + } + + assert_raise(TypeError) { + mat.find_chessboard_corners(DUMMY_OBJ) + } + assert_raise(TypeError) { + mat.find_chessboard_corners(pattern_size, DUMMY_OBJ) + } + end + + def test_find_corner_sub_pix + mat = CvMat.load(FILENAME_CHESSBOARD, CV_LOAD_IMAGE_GRAYSCALE) + pattern_size = CvSize.new(4, 4) + corners, found = mat.find_chessboard_corners(pattern_size) + expected = [[39, 39], [79, 39], [119, 39], [159, 39], [39, 79], [79, 79], + [119, 79], [159, 78], [38, 119], [79, 119], [119, 119], [158, 118], + [39, 159], [79, 159], [119, 159], [159, 159]] + + refined_corners = mat.find_corner_sub_pix(corners, CvSize.new(3, 3), CvSize.new(-1, -1), + CvTermCriteria.new(20, 0.03)); + assert_equal(expected.size, refined_corners.size) + assert(found) + expected.zip(refined_corners).each { |e, a| + assert_in_delta(e[0], a.x, 3.0) + assert_in_delta(e[1], a.y, 3.0) + } + + assert_raise(TypeError) { + mat.find_corner_sub_pix(DUMMY_OBJ, CvSize.new(3, 3), CvSize.new(-1, -1), + CvTermCriteria.new(20, 0.03)); + } + assert_raise(TypeError) { + mat.find_corner_sub_pix(corners, DUMMY_OBJ, CvSize.new(-1, -1), + CvTermCriteria.new(20, 0.03)); + } + assert_raise(TypeError) { + mat.find_corner_sub_pix(corners, CvSize.new(3, 3), DUMMY_OBJ, + CvTermCriteria.new(20, 0.03)); + } + assert_raise(TypeError) { + mat.find_corner_sub_pix(corners, CvSize.new(3, 3), CvSize.new(-1, -1), DUMMY_OBJ); + } + end + + def test_good_features_to_track + mat0 = CvMat.load(FILENAME_LENA32x32, CV_LOAD_IMAGE_GRAYSCALE) + mask = create_cvmat(mat0.rows, mat0.cols, :cv8u, 1) { |j, i, c| + if (i > 8 and i < 18) and (j > 8 and j < 18) + CvScalar.new(1) + else + CvScalar.new(0) + end + } + + corners1 = mat0.good_features_to_track(0.2, 5) + corners2 = mat0.good_features_to_track(0.2, 5, :mask => mask) + corners3 = mat0.good_features_to_track(0.2, 5, :block_size => 7) + corners4 = mat0.good_features_to_track(0.2, 5, :use_harris => true) + corners5 = mat0.good_features_to_track(0.2, 5, :k => 0.01) + corners6 = mat0.good_features_to_track(0.2, 5, :max => 1) + + expected1 = [[24, 7], [20, 23], [17, 11], [26, 29], [30, 24], + [19, 16], [28, 2], [13, 18], [14, 4]] + assert_equal(expected1.size, corners1.size) + expected1.each_with_index { |e, i| + assert_equal(e[0], corners1[i].x.to_i) + assert_equal(e[1], corners1[i].y.to_i) + } + expected2 = [[17, 11], [17, 16]] + assert_equal(expected2.size, corners2.size) + expected2.each_with_index { |e, i| + assert_equal(e[0], corners2[i].x.to_i) + assert_equal(e[1], corners2[i].y.to_i) + } + + expected3 = [[21, 7], [22, 23], [18, 12], [28, 4], [28, 26], + [17, 27], [13, 20], [10, 11], [14, 5]] + assert_equal(expected3.size, corners3.size) + expected3.each_with_index { |e, i| + assert_equal(e[0], corners3[i].x.to_i) + assert_equal(e[1], corners3[i].y.to_i) + } + + expected4 = [[24, 8], [20, 23], [16, 11], + [20, 16],[27, 28], [28, 2]] + assert_equal(expected4.size, corners4.size) + expected4.each_with_index { |e, i| + assert_equal(e[0], corners4[i].x.to_i) + assert_equal(e[1], corners4[i].y.to_i) + } + + expected5 = [[24, 7], [20, 23], [17, 11], [26, 29], [30, 24], + [19, 16], [28, 2], [13, 18], [14, 4]] + assert_equal(expected5.size, corners5.size) + expected5.each_with_index { |e, i| + assert_equal(e[0], corners5[i].x.to_i) + assert_equal(e[1], corners5[i].y.to_i) + } + + assert_equal(1, corners6.size) + assert_equal(24, corners6[0].x.to_i) + assert_equal(7, corners6[0].y.to_i) + + assert_raise(ArgumentError) { + mat0.good_features_to_track(0.2, 5, :max => 0) + } + + assert_raise(TypeError) { + mat0.good_features_to_track(DUMMY_OBJ, 5) + } + assert_raise(TypeError) { + mat0.good_features_to_track(0.2, DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.good_features_to_track(0.2, 5, :mask => DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.good_features_to_track(0.2, 5, :block_size => DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.good_features_to_track(0.2, 5, :k => DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.good_features_to_track(0.2, 5, :max => DUMMY_OBJ) + } + mat0.good_features_to_track(0.2, 5, :use_harris => DUMMY_OBJ) + end + + def test_rect_sub_pix + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + center = CvPoint2D32f.new(mat0.width / 2, mat0.height / 2) + mat1 = mat0.rect_sub_pix(center) + mat2 = mat0.rect_sub_pix(center, mat0.size) + mat3 = mat0.rect_sub_pix(center, CvSize.new(512, 512)) + + assert_equal('b3dc0e31260dd42b5341471e23e825d3', hash_img(mat1)) + assert_equal('b3dc0e31260dd42b5341471e23e825d3', hash_img(mat2)) + assert_equal('cc27ce8f4068efedcd31c4c782c3825c', hash_img(mat3)) + + assert_raise(TypeError) { + mat0.rect_sub_pix(DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.rect_sub_pix(center, DUMMY_OBJ) + } + end + + def test_quadrangle_sub_pix + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + angle = 60 * Math::PI / 180 + map_matrix = CvMat.new(2, 3, :cv32f, 1) + map_matrix[0] = CvScalar.new(Math.cos(angle)) + map_matrix[1] = CvScalar.new(-Math.sin(angle)) + map_matrix[2] = CvScalar.new(mat0.width * 0.5) + map_matrix[3] = CvScalar.new(-map_matrix[1][0]) + map_matrix[4] = map_matrix[0] + map_matrix[5] = CvScalar.new(mat0.height * 0.5) + + mat1 = mat0.quadrangle_sub_pix(map_matrix) + mat2 = mat0.quadrangle_sub_pix(map_matrix, mat0.size) + mat3 = mat0.quadrangle_sub_pix(map_matrix, CvSize.new(512, 512)) + + assert_equal('f170c05fa50c3ac2a762d7b3f5c4ae2f', hash_img(mat1)) + assert_equal('f170c05fa50c3ac2a762d7b3f5c4ae2f', hash_img(mat2)) + assert_equal('4d949d5083405381ad9ea09dcd95e5a2', hash_img(mat3)) + + assert_raise(TypeError) { + mat0.quadrangle_sub_pix(DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.quadrangle_sub_pix(map_matrix, DUMMY_OBJ) + } + # assert_raise(CvError) { + # mat0.quadrangle_sub_pix(CvMat.new(3, 3)) + # } + end + + def test_resize + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + size = CvSize.new(384, 384) + mat1 = mat0.resize(size) + mat2 = mat0.resize(size, CV_INTER_LINEAR) + mat3 = mat0.resize(size, CV_INTER_NN) + mat4 = mat0.resize(size, CV_INTER_AREA) + mat5 = mat0.resize(size, CV_INTER_CUBIC) + mat6 = mat0.resize(size, CV_INTER_LANCZOS4) + + [mat1, mat2, mat3, mat4, mat5, mat6].each { |m| + assert_equal(size.width, m.cols) + assert_equal(size.height, m.rows) + assert_equal(mat0.depth, m.depth) + assert_equal(mat0.channel, m.channel) + } + + assert_raise(TypeError) { + mat0.resize(DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.resize(size, DUMMY_OBJ) + } + + # Uncomment the following lines to show the results + # snap(['original', mat0], ['default(linear)', mat1], ['linear', mat2], + # ['nn', mat3], ['area', mat4], ['cubic', mat5] , ['lanczos4', mat6]) + end + + def test_warp_affine + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + map_matrix = CvMat.new(2, 3, :cv32f, 1) + # center: (128, 128), angle: 25 deg., scale: 1.0 + map_matrix[0] = CvScalar.new(0.90631) + map_matrix[1] = CvScalar.new(0.42262) + map_matrix[2] = CvScalar.new(-42.10254) + map_matrix[3] = CvScalar.new(-0.42262) + map_matrix[4] = CvScalar.new(0.90631) + map_matrix[5] = CvScalar.new(66.08774) + + mat1 = mat0.warp_affine(map_matrix) + mat2 = mat0.warp_affine(map_matrix, CV_INTER_NN | CV_WARP_FILL_OUTLIERS) + mat3 = mat0.warp_affine(map_matrix, CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS, CvColor::Yellow) + mat4 = mat0.warp_affine(map_matrix, CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS | CV_WARP_INVERSE_MAP) + + [mat1, mat2, mat3, mat4].each { |m| + assert_equal(mat0.cols, m.cols) + assert_equal(mat0.rows, m.rows) + assert_equal(mat0.depth, m.depth) + assert_equal(mat0.channel, m.channel) + } + + assert_raise(TypeError) { + mat0.warp_affine(DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.warp_affine(map_matrix, DUMMY_OBJ) + } + + # Uncomment the following lines to show the results + # snap mat0, mat1, mat2, mat3, mat4 + end + + def test_get_perspective_transform + from = [ + OpenCV::CvPoint2D32f.new(540, 382), + OpenCV::CvPoint2D32f.new(802, 400), + OpenCV::CvPoint2D32f.new(850, 731), + OpenCV::CvPoint2D32f.new(540, 731), + ] + to = [ + OpenCV::CvPoint2D32f.new(0, 0), + OpenCV::CvPoint2D32f.new(233, 0), + OpenCV::CvPoint2D32f.new(233, 310), + OpenCV::CvPoint2D32f.new(0, 310), + ] + transform = OpenCV::CvMat.get_perspective_transform(from, to) + assert_equal 3, transform.rows + assert_equal 3, transform.columns + expected = [ + 0.923332154750824, + 0.0, + 0.0, + 1.4432899320127035e-15, + 0.0, + 0.0, + -498.599365234375, + 0.0, + 0.0, + ] + 3.times do |i| + 3.times do |j| + assert_in_delta(expected.shift, transform[i][j], 0.001) + end + end + end + + def test_rotation_matrix2D + mat1 = CvMat.rotation_matrix2D(CvPoint2D32f.new(10, 20), 60, 2.0) + expected = [1.0, 1.73205, -34.64102, + -1.73205, 1.0, 17.32051] + assert_equal(2, mat1.rows) + assert_equal(3, mat1.cols) + assert_equal(:cv32f, mat1.depth) + assert_equal(1, mat1.channel) + expected.each_with_index { |x, i| + assert_in_delta(x, mat1[i][0], 0.001) + } + + assert_raise(TypeError) { + CvMat.rotation_matrix2D(DUMMY_OBJ, 60, 2.0) + } + assert_raise(TypeError) { + CvMat.rotation_matrix2D(CvPoint2D32f.new(10, 20), DUMMY_OBJ, 2.0) + } + assert_raise(TypeError) { + CvMat.rotation_matrix2D(CvPoint2D32f.new(10, 20), 60, DUMMY_OBJ) + } + end + + def test_warp_perspective + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + # Homography + # => + # (0, 0) => (50, 0) + # (255, 0) => (205, 0) + # (255, 255) => (255, 220) + # (0, 255) => (0, 275) + map_matrix = CvMat.new(3, 3, :cv32f, 1) + map_matrix[0] = CvScalar.new(0.72430) + map_matrix[1] = CvScalar.new(-0.19608) + map_matrix[2] = CvScalar.new(50.00000) + map_matrix[3] = CvScalar.new(0.0) + map_matrix[4] = CvScalar.new(0.62489) + map_matrix[5] = CvScalar.new(0.0) + map_matrix[6] = CvScalar.new(0.00057) + map_matrix[7] = CvScalar.new(-0.00165) + map_matrix[8] = CvScalar.new(1.00000) + + mat1 = mat0.warp_perspective(map_matrix) + mat2 = mat0.warp_perspective(map_matrix, CV_INTER_NN) + mat3 = mat0.warp_perspective(map_matrix, CV_INTER_LINEAR | CV_WARP_INVERSE_MAP) + mat4 = mat0.warp_perspective(map_matrix, CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS, CvColor::Yellow) + + [mat1, mat2, mat3, mat4].each { |m| + assert_equal(mat0.cols, m.cols) + assert_equal(mat0.rows, m.rows) + assert_equal(mat0.depth, m.depth) + assert_equal(mat0.channel, m.channel) + } + + assert_raise(TypeError) { + mat0.warp_perspective(DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.warp_perspective(map_matrix, DUMMY_OBJ) + } + + # Uncomment the following line to show the results + # snap mat0, mat1, mat2, mat3, mat4 + end + + def test_remap + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + matx = CvMat.new(mat0.height, mat0.width, :cv32f, 1).clear + maty = CvMat.new(mat0.height, mat0.width, :cv32f, 1).clear + + cos30, sin30 = Math.cos(30 * Math::PI / 180), Math.sin(30 * Math::PI / 180) + half_width, half_height = mat0.width / 2, mat0.height / 2 + mat0.height.times { |j| + mat0.width.times { |i| + x0 = i - half_width + y0 = j - half_height + x = x0 * cos30 - y0 * sin30 + half_width + y = x0 * sin30 + y0 * cos30 + half_height + matx[j, i] = CvScalar.new(x) + maty[j, i] = CvScalar.new(y) + } + } + + mat1 = mat0.remap(matx, maty) + mat2 = mat0.remap(matx, maty, CV_INTER_NN) + mat3 = mat0.remap(matx, maty, CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS, CvColor::Yellow) + + [mat1, mat2, mat3].each { |m| + assert_equal(mat0.cols, m.cols) + assert_equal(mat0.rows, m.rows) + assert_equal(mat0.depth, m.depth) + assert_equal(mat0.channel, m.channel) + } + + assert_raise(TypeError) { + mat0.remap(DUMMY_OBJ, maty) + } + assert_raise(TypeError) { + mat0.remap(matx, DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.remap(matx, maty, DUMMY_OBJ) + } + + # Uncomment the following line to show the results + # snap mat0, mat1, mat2, mat3 + end + + def test_log_polar + mat0 = CvMat.load(FILENAME_FRUITS, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + + mat1 = mat0.log_polar(CvSize.new(255, 255), CvPoint2D32f.new(mat0.width / 2, mat0.height / 2), 40) + mat2 = mat0.log_polar(CvSize.new(255, 255), CvPoint2D32f.new(mat0.width / 2, mat0.height / 2), 40, + CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS) + mat3 = mat1.log_polar(mat0.size, CvPoint2D32f.new(mat0.width / 2, mat0.height / 2), 40, + CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS | CV_WARP_INVERSE_MAP) + + [mat1, mat2].each { |mat| + assert_equal(mat0.depth, mat.depth) + assert_equal(mat0.channel, mat.channel) + b, g, r = color_hists(mat) + assert_in_delta(4000000, b, 100000) + assert_in_delta(5860000, g, 100000) + assert_in_delta(7700000, r, 100000) + } + + b, g, r = color_hists(mat3) + assert_equal(mat0.depth, mat3.depth) + assert_equal(mat0.channel, mat3.channel) + assert_in_delta(11200000, b, 1000000) + assert_in_delta(20800000, g, 1000000) + assert_in_delta(26900000, r, 1000000) + + # Uncomment the following line to show the results + # snap mat0, mat1, mat2 + end + + def test_erode + mat0 = create_cvmat(9, 9, :cv8u, 1) { |j, i, c| + if i >= 3 and i < 6 and j >= 3 and j < 6 + CvScalar.new(255) + else + CvScalar.new(0) + end + } + + mat1 = create_cvmat(9, 9, :cv8u, 1) { |j, i, c| + if i >= 1 and i < 8 and j >= 1 and j < 8 + CvScalar.new(255) + else + CvScalar.new(0) + end + } + + mat2 = create_cvmat(5, 5, :cv8u, 1) { |j, i, c| + if i == 2 or j == 2 + CvScalar.new(255) + else + CvScalar.new(0) + end + } + + mat3 = mat0.erode + mat4 = mat0.erode(nil, 1) + mat5 = mat1.erode(nil, 2) + mat6 = mat1.erode(IplConvKernel.new(5, 5, 2, 2, :cross)) + mat7 = mat0.clone + mat7.erode! + + assert_equal('075eb0e281328f768eb862735d16979d', hash_img(mat3)) + assert_equal('075eb0e281328f768eb862735d16979d', hash_img(mat4)) + assert_equal('9f02fc4438b1d69fea75a10dfd2b66b0', hash_img(mat5)) + assert_equal('9f02fc4438b1d69fea75a10dfd2b66b0', hash_img(mat6)) + assert_equal('075eb0e281328f768eb862735d16979d', hash_img(mat7)) + + assert_raise(TypeError) { + mat0.erode(DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.erode(nil, DUMMY_OBJ) + } + end + + def test_dilate + mat0 = create_cvmat(9, 9, :cv8u, 1) { |j, i, c| + if i == 4 and j == 4 + CvScalar.new(255) + else + CvScalar.new(0) + end + } + + mat1 = create_cvmat(5, 5, :cv8u, 1) { |j, i, c| + if i == 2 or j == 2 + CvScalar.new(255) + else + CvScalar.new(0) + end + } + + mat2 = mat0.dilate + mat3 = mat0.dilate(nil, 1) + mat4 = mat0.dilate(nil, 2) + mat5 = mat1.dilate(IplConvKernel.new(5, 5, 2, 2, :cross)) + mat6 = mat0.clone + mat6.dilate! + + assert_equal('9f02fc4438b1d69fea75a10dfd2b66b0', hash_img(mat2)) + assert_equal('9f02fc4438b1d69fea75a10dfd2b66b0', hash_img(mat3)) + assert_equal('ebf07f2a0edd2fd0fe26ff5921c6871b', hash_img(mat4)) + assert_equal('2841937c35c311e947bee49864b9d295', hash_img(mat5)) + assert_equal('9f02fc4438b1d69fea75a10dfd2b66b0', hash_img(mat6)) + + assert_raise(TypeError) { + mat0.dilate(DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.dilate(nil, DUMMY_OBJ) + } + end + + def test_morphology + mat0 = create_cvmat(64, 64, :cv8u, 1) { |j, i, c| + if i >= 8 and i < 56 and j >= 8 and j < 56 and (i + j) % 15 != 0 + CvScalar.new(255) + else + CvScalar.new(0) + end + } + + # Open + kernel = IplConvKernel.new(5, 5, 2, 2, :cross) + mat1 = mat0.morphology(CV_MOP_OPEN, kernel) + mat2 = mat0.morphology(:open, kernel) + assert_equal('63ccb07cb93efb1563657f51e3d89252', hash_img(mat1)) + assert_equal('63ccb07cb93efb1563657f51e3d89252', hash_img(mat2)) + + # Close + mat1 = mat0.morphology(CV_MOP_CLOSE, kernel) + mat2 = mat0.morphology(:close, kernel) + assert_equal('831c513d6ed86bce3f15c697de4a72f8', hash_img(mat1)) + assert_equal('831c513d6ed86bce3f15c697de4a72f8', hash_img(mat2)) + + # Gradient + mat1 = mat0.morphology(CV_MOP_GRADIENT, kernel) + mat2 = mat0.morphology(:gradient, kernel) + assert_equal('1e8007c211d6f464cf8584e8e83b3c35', hash_img(mat1)) + assert_equal('1e8007c211d6f464cf8584e8e83b3c35', hash_img(mat2)) + + # Top hat + mat1 = mat0.morphology(CV_MOP_TOPHAT, kernel) + mat2 = mat0.morphology(:tophat, kernel) + assert_equal('1760c5b63a52df37069164fe3e901aa4', hash_img(mat1)) + assert_equal('1760c5b63a52df37069164fe3e901aa4', hash_img(mat2)) + + # Black hat + mat1 = mat0.morphology(CV_MOP_BLACKHAT, kernel) + mat2 = mat0.morphology(:blackhat, kernel) + assert_equal('18b1d51637b912a38133341ee006c6ff', hash_img(mat1)) + assert_equal('18b1d51637b912a38133341ee006c6ff', hash_img(mat2)) + + [:open, :close, :gradient, :tophat, :blackhat].each { |type| + assert_raise(TypeError) { + mat0.morphology(type, DUMMY_OBJ) + } + } + end + + def test_smooth + mat0 = CvMat.load(FILENAME_LENA32x32, CV_LOAD_IMAGE_GRAYSCALE) + + assert_raise(TypeError) { + mat0.smooth(DUMMY_OBJ) + } + + # Blur no scale + mat1 = mat0.smooth(CV_BLUR_NO_SCALE) + mat2 = mat0.smooth(:blur_no_scale, 3, 3) + mat3 = mat0.smooth(CV_BLUR_NO_SCALE, 7, 7) + mat4 = CvMat.new(32, 32, :cv32f, 1).smooth(:blur_no_scale) + + [mat1, mat2, mat3].each { |m| + assert_equal(1, m.channel) + assert_equal(:cv16u, m.depth) + } + assert_equal(1, mat4.channel) + assert_equal(:cv32f, mat4.depth) + + assert_equal('3c9074c87b65117798f48e41a17b2f30', hash_img(mat1)) + assert_equal('3c9074c87b65117798f48e41a17b2f30', hash_img(mat2)) + assert_equal('9c549aa406a425a65b036c2f9a2689e0', hash_img(mat3)) + + assert_raise(TypeError) { + mat0.smooth(CV_BLUR_NO_SCALE, DUMMY_OBJ, 0, 0, 0) + } + assert_raise(TypeError) { + mat0.smooth(CV_BLUR_NO_SCALE, 3, DUMMY_OBJ, 0, 0) + } + + # Blur + mat1 = mat0.smooth(CV_BLUR) + mat2 = mat0.smooth(:blur, 3, 3) + mat3 = mat0.smooth(CV_BLUR, 7, 7) + mat4 = CvMat.new(32, 32, :cv16u, 1).smooth(:blur) + mat5 = CvMat.new(32, 32, :cv32f, 1).smooth(CV_BLUR) + mat6 = CvMat.new(32, 32, :cv8u, 3).smooth(:blur) + + [mat1, mat2, mat3].each { |m| + assert_equal(1, m.channel) + assert_equal(:cv8u, m.depth) + } + assert_equal(1, mat4.channel) + assert_equal(:cv16u, mat4.depth) + assert_equal(1, mat5.channel) + assert_equal(:cv32f, mat5.depth) + assert_equal(3, mat6.channel) + assert_equal(:cv8u, mat6.depth) + + assert_equal('f2473b5b964ae8950f6a7fa5cde4c67a', hash_img(mat1)) + assert_equal('f2473b5b964ae8950f6a7fa5cde4c67a', hash_img(mat2)) + assert_equal('d7bb344fc0f6ec0da4b9754d319e4e4a', hash_img(mat3)) + + assert_raise(TypeError) { + mat0.smooth(CV_BLUR, DUMMY_OBJ, 0, 0, 0) + } + assert_raise(TypeError) { + mat0.smooth(CV_BLUR, 3, DUMMY_OBJ, 0, 0) + } + + # Gaussian + mat1 = mat0.smooth(CV_GAUSSIAN) + mat2 = mat0.smooth(:gaussian, 3, 3) + mat3 = mat0.smooth(CV_GAUSSIAN, 3, 3, 3) + mat4 = mat0.smooth(:gaussian, 3, 3, 3, 3) + mat5 = mat0.smooth(CV_GAUSSIAN, 7, 7, 5, 3) + + mat6 = CvMat.new(32, 32, :cv16u, 1).smooth(CV_GAUSSIAN) + mat7 = CvMat.new(32, 32, :cv32f, 1).smooth(CV_GAUSSIAN) + mat8 = CvMat.new(32, 32, :cv8u, 3).smooth(CV_GAUSSIAN) + + [mat1, mat2, mat3, mat4, mat5].each { |m| + assert_equal(1, m.channel) + assert_equal(:cv8u, m.depth) + } + assert_equal(1, mat6.channel) + assert_equal(:cv16u, mat6.depth) + assert_equal(1, mat7.channel) + assert_equal(:cv32f, mat7.depth) + assert_equal(3, mat8.channel) + assert_equal(:cv8u, mat8.depth) + + assert_equal('580c88f3e0e317a5770be3f28f31eda2', hash_img(mat1)) + assert_equal('580c88f3e0e317a5770be3f28f31eda2', hash_img(mat2)) + assert_equal('a1ffaa14522719e37d75eec18ff8b309', hash_img(mat3)) + assert_equal('a1ffaa14522719e37d75eec18ff8b309', hash_img(mat4)) + assert_equal('f7f8b4eff3240ffc8f259ce975936d92', hash_img(mat5)) + + assert_raise(TypeError) { + mat0.smooth(CV_GAUSSIAN, DUMMY_OBJ, 0, 0, 0) + } + assert_raise(TypeError) { + mat0.smooth(CV_GAUSSIAN, 3, DUMMY_OBJ, 0, 0) + } + assert_raise(TypeError) { + mat0.smooth(CV_GAUSSIAN, 3, 0, DUMMY_OBJ, 0) + } + assert_raise(TypeError) { + mat0.smooth(CV_GAUSSIAN, 3, 0, 0, DUMMY_OBJ) + } + + # Median + mat0 = create_cvmat(64, 64, :cv8u, 1) { |j, i, c| + if (i + j) % 15 != 0 + CvScalar.new(255) + else + CvScalar.new(0) + end + } + (-1..1).each { |dy| + (-1..1).each { |dx| + mat0[32 + dy, 32 + dx] = CvScalar.new(0) + } + } + + mat1 = mat0.smooth(CV_MEDIAN) + mat2 = mat0.smooth(:median, 3) + mat3 = mat0.smooth(CV_MEDIAN, 7) + mat4 = CvMat.new(64, 64, :cv8u, 3).smooth(CV_MEDIAN) + + assert_equal('7343a41c542e034db356636c06134961', hash_img(mat1)) + assert_equal('7343a41c542e034db356636c06134961', hash_img(mat2)) + assert_equal('6ae59e64850377ee5470c854761551ea', hash_img(mat3)) + + assert_raise(TypeError) { + mat0.smooth(CV_MEDIAN, DUMMY_OBJ, 0, 0, 0) + } + + # Bilateral + mat0 = create_cvmat(64, 64, :cv8u, 1) { |j, i, c| + if i > 32 + (i + j) % 15 != 0 ? CvScalar.new(32) : CvScalar.new(224) + else + (i + j) % 15 != 0 ? CvScalar.new(224) : CvScalar.new(32) + end + } + + mat1 = mat0.smooth(CV_BILATERAL) + mat2 = mat0.smooth(:bilateral, 3, 3) + mat3 = mat0.smooth(CV_BILATERAL, 7, 7) + mat4 = CvMat.new(64, 64, :cv8u, 3).smooth(CV_BILATERAL) + + assert_raise(TypeError) { + mat0.smooth(CV_BILATERAL, DUMMY_OBJ, 0, 0, 0) + } + assert_raise(TypeError) { + mat0.smooth(CV_BILATERAL, 3, DUMMY_OBJ, 0, 0) + } + + flunk('FIXME: Cases of CvMat#smooth(CV_BILATERAL) are not tested yet.') + end + + def test_filter2d + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_GRAYSCALE) + kernel = CvMat.new(3, 3, :cv32f, 1) + + # Laplacian filter kernel + laplace4 = [0, 1, 0, + 1, -4, 1, + 0, 1, 0] + laplace4.each_with_index { |x, i| kernel[i] = CvScalar.new(x) } + + mat1 = mat0.filter2d(kernel) + mat2 = mat0.filter2d(kernel, CvPoint.new(-1, -1)) + mat3 = mat0.filter2d(kernel, CvPoint.new(0, 0)) + + assert_equal('14a01cc47078e8f8fe4f0fd510d5521b', hash_img(mat1)) + assert_equal('14a01cc47078e8f8fe4f0fd510d5521b', hash_img(mat2)) + assert_equal('30e04de43f9240df6aadbaea6467b8fe', hash_img(mat3)) + + assert_raise(TypeError) { + mat0.filter2d(DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.filter2d(kernel, DUMMY_OBJ) + } + end + + def test_copy_make_border + mat0 = create_cvmat(32, 32, :cv8u, 1) { CvScalar.new(128) } + + [IPL_BORDER_CONSTANT, :constant].each { |type| + mat1 = mat0.copy_make_border(type, CvSize.new(64, 48), CvPoint.new(16, 8), 255) + assert_equal('5e231f8ca051b8f93e4aaa42d193d095', hash_img(mat1)) + } + + [IPL_BORDER_REPLICATE, :replicate].each { |type| + mat2 = mat0.copy_make_border(type, CvSize.new(300, 300), CvPoint.new(30, 30)) + assert_equal('96940dc9e3abb6e2556ea51af1468031', hash_img(mat2)) + } + + assert_raise(TypeError) { + mat0.copy_make_border(DUMMY_OBJ, CvSize.new(64, 48), CvPoint.new(16, 8)) + } + assert_raise(TypeError) { + mat0.copy_make_border(IPL_BORDER_CONSTANT, CvSize.new(64, 48), DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.copy_make_border(IPL_BORDER_CONSTANT, CvSize.new(64, 48), CvPoint.new(16, 8), DUMMY_OBJ) + } + assert_raise(ArgumentError) { + mat0.copy_make_border(:dummy, CvSize.new(64, 48), CvPoint.new(16, 8), DUMMY_OBJ) + } + end + + def test_integral + mat0 = create_cvmat(3, 3, :cv8u, 1) { |j, i, n| CvScalar.new(n) } + + result_sum = [] + result_sqsum = [] + result_tiled_sum = [] + + result1 = mat0.integral + assert_equal(CvMat, result1.class) + result_sum << result1 + + result2 = mat0.integral(true) + assert_equal(Array, result2.class) + assert_equal(2, result2.size) + assert(result2.all? {|a| a.class == CvMat}) + result_sum << result2[0] + result_sqsum << result2[1] + + result3 = mat0.integral(true, true) + assert_equal(Array, result3.class) + assert_equal(3, result3.size) + assert(result3.all? {|a| a.class == CvMat}) + result_sum << result3[0] + result_sqsum << result3[1] + result_tiled_sum << result3[2] + + result4 = mat0.integral(true, false) + assert_equal(Array, result4.class) + assert_equal(2, result4.size) + assert(result4.all? {|a| a.class == CvMat}) + result_sum << result4[0] + result_sqsum << result4[1] + + result5 = mat0.integral(false, true) + assert_equal(Array, result5.class) + assert_equal(2, result5.size) + assert(result5.all? {|a| a.class == CvMat}) + result_sum << result5[0] + result_tiled_sum << result5[1] + + (result_sum + result_sqsum + result_tiled_sum).each { |s| + assert_equal(mat0.height + 1, s.height) + assert_equal(mat0.width + 1, s.width) + assert_equal(:cv64f, s.depth) + assert_equal(1, s.channel) + } + + expected_sum = [0, 0, 0, 0, + 0, 0, 1, 3, + 0, 3, 8, 15, + 0, 9, 21, 36] + result_sum.each { |sum| + expected_sum.each_with_index { |x, i| + assert_in_delta(x, sum[i][0], 0.001) + } + } + + expected_sqsum = [0, 0, 0, 0, + 0, 0, 1, 5, + 0, 9, 26, 55, + 0, 45, 111, 204] + result_sqsum.each { |sqsum| + expected_sqsum.each_with_index { |x, i| + assert_in_delta(x, sqsum[i][0], 0.001) + } + } + + expected_tilted_sum = [0, 0, 0, 0, + 0, 0, 1, 2, + 0, 4, 7, 8, + 4, 16, 22, 20] + result_tiled_sum.each { |tiled_sum| + expected_tilted_sum.each_with_index { |x, i| + assert_in_delta(x, tiled_sum[i][0], 0.001) + } + } + + mat0.integral(DUMMY_OBJ, DUMMY_OBJ) + end + + def test_threshold + mat0 = create_cvmat(3, 3, :cv8u, 1) { |j, i, n| CvScalar.new(n) } + test_proc = lambda { |type, type_sym, expected_mat, expected_threshold| + mat1 = mat0.threshold(expected_threshold, 7, type) + mat2 = mat0.threshold(expected_threshold, 7, type_sym) + [mat1, mat2].each { |m| + expected_mat.each_with_index { |x, i| + assert_equal(x, m[i][0]) + } + } + } + + test_proc_with_otsu = lambda { |type, type_sym, expected_mat, expected_threshold| + mat3, th3 = mat0.threshold(5, 7, type | CV_THRESH_OTSU) + mat4, th4 = mat0.threshold(3, 7, type_sym, true) + mat5, th5 = mat0.threshold(5, 7, type | CV_THRESH_OTSU, true) + [mat3, mat4, mat5].each { |m| + expected_mat.each_with_index { |x, i| + assert_equal(x, m[i][0]) + } + } + [th3, th4, th5].each { |th| + assert_in_delta(expected_threshold, th, 0.001) + } + } + + # Binary + expected = [0, 0, 0, + 0, 0, 7, + 7, 7, 7] + test_proc.call(CV_THRESH_BINARY, :binary, expected, 4) + + expected = [0, 0, 0, + 0, 7, 7, + 7, 7, 7] + test_proc_with_otsu.call(CV_THRESH_BINARY, :binary, expected, 3) + + # Binary inverse + expected = [7, 7, 7, + 7, 7, 0, + 0, 0, 0] + test_proc.call(CV_THRESH_BINARY_INV, :binary_inv, expected, 4) + + expected = [7, 7, 7, + 7, 0, 0, + 0, 0, 0] + test_proc_with_otsu.call(CV_THRESH_BINARY_INV, :binary_inv, expected, 3) + + # Trunc + expected = [0, 1, 2, + 3, 4, 4, + 4, 4, 4] + test_proc.call(CV_THRESH_TRUNC, :trunc, expected, 4) + + expected = [0, 1, 2, + 3, 3, 3, + 3, 3, 3] + test_proc_with_otsu.call(CV_THRESH_TRUNC, :trunc, expected, 3) + + # To zero + expected = [0, 0, 0, + 0, 0, 5, + 6, 7, 8] + test_proc.call(CV_THRESH_TOZERO, :tozero, expected, 4) + + expected = [0, 0, 0, + 0, 4, 5, + 6, 7, 8] + test_proc_with_otsu.call(CV_THRESH_TOZERO, :tozero, expected, 3) + + # To zero inverse + expected = [0, 1, 2, + 3, 4, 0, + 0, 0, 0] + test_proc.call(CV_THRESH_TOZERO_INV, :tozero_inv, expected, 4) + + expected = [0, 1, 2, + 3, 0, 0, + 0, 0, 0] + test_proc_with_otsu.call(CV_THRESH_TOZERO_INV, :tozero_inv, expected, 3) + + assert_raise(TypeError) { + mat0.threshold(DUMMY_OBJ, 2, :binary) + } + assert_raise(TypeError) { + mat0.threshold(1, DUMMY_OBJ, :binary) + } + assert_raise(TypeError) { + mat0.threshold(1, 2, DUMMY_OBJ) + } + assert_raise(ArgumentError) { + mat0.threshold(1, 2, :dummy) + } + mat0.threshold(1, 2, :binary, DUMMY_OBJ) + end + + def test_adaptive_threshold + mat0 = create_cvmat(5, 5, :cv8u, 1) { |j, i, c| (c + 1) * 10 } + + mat1 = mat0.adaptive_threshold(128) + expected1 = [0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128] + expected1.each_with_index { |expected, i| + assert_equal(expected, mat1[i][0]) + } + + mat2a = mat0.adaptive_threshold(255, :adaptive_method => :mean_c, + :threshold_type => :binary, :block_size => 5, + :param1 => 10) + mat2b = mat0.adaptive_threshold(255, :adaptive_method => CV_THRESH_BINARY, + :threshold_type => CV_ADAPTIVE_THRESH_MEAN_C, :block_size => 5, + :param1 => 10) + expected2 = [0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255] + [mat2a, mat2b].each { |mat2| + assert_equal(CvMat, mat2.class) + assert_equal(mat0.rows, mat2.rows) + assert_equal(mat0.cols, mat2.cols) + assert_equal(mat0.depth, mat2.depth) + assert_equal(mat0.channel, mat2.channel) + expected2.each_with_index { |expected, i| + assert_equal(expected, mat2[i][0]) + } + } + + + mat3a = mat0.adaptive_threshold(255, :adaptive_method => :gaussian_c, + :threshold_type => :binary_inv, :block_size => 5, + :param1 => 10) + mat3b = mat0.adaptive_threshold(255, :adaptive_method => CV_ADAPTIVE_THRESH_GAUSSIAN_C, + :threshold_type => CV_THRESH_BINARY_INV, :block_size => 5, + :param1 => 10) + expected3 = [255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + [mat3a, mat3b].each { |mat3| + assert_equal(CvMat, mat3.class) + assert_equal(mat0.rows, mat3.rows) + assert_equal(mat0.cols, mat3.cols) + assert_equal(mat0.depth, mat3.depth) + assert_equal(mat0.channel, mat3.channel) + expected3.each_with_index { |expected, i| + assert_equal(expected, mat3[i][0]) + } + } + + assert_raise(TypeError) { + mat0.adaptive_threshold(DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.adaptive_threshold(0, DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.adaptive_threshold(0, :adaptive_method => DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.adaptive_threshold(0, :threshold_type => DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.adaptive_threshold(0, :block_size => DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.adaptive_threshold(0, :param1 => DUMMY_OBJ) + } + end + + def test_pyr_down + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + mat1 = mat0.pyr_down + mat2 = mat0.pyr_down(:gaussian_5x5) + + assert_equal('de9ff2ffcf8e43f28564a201cf90b7f4', hash_img(mat1)) + assert_equal('de9ff2ffcf8e43f28564a201cf90b7f4', hash_img(mat2)) + + assert_raise(TypeError) { + mat0.pyr_down(DUMMY_OBJ) + } + end + + def test_pyr_up + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + mat1 = mat0.pyr_up + mat2 = mat0.pyr_up(:gaussian_5x5) + + [mat1, mat2].each { |mat| + assert_equal(mat0.cols * 2, mat.cols) + assert_equal(mat0.rows * 2, mat.rows) + assert_equal(mat0.depth, mat.depth) + assert_equal(mat0.channel, mat.channel) + b, g, r = color_hists(mat) + assert_in_delta(27500000, b, 1000000) + assert_in_delta(26000000, g, 1000000) + assert_in_delta(47000000, r, 1000000) + } + # Uncomment the following lines to show the result + # snap mat0, mat1, mat2 + + assert_raise(TypeError) { + mat0.pyr_up(DUMMY_OBJ) + } + end + + def test_flood_fill + mat0 = create_cvmat(128, 256, :cv8u, 1) { |j, i, c| + if (i >= 32 and i < 224) and (j >= 32 and j < 96) + CvScalar.new(255) + elsif (i >= 16 and i < 240) and (j >= 16 and j < 112) + CvScalar.new(192) + else + CvScalar.new(128) + end + } + + point = CvPoint.new(20, 20) + mat1, comp1, mask1 = mat0.flood_fill(point, 0) + mat2, comp2, mask2 = mat0.flood_fill(point, 0, CvScalar.new(64)) + mat3, comp3, mask3 = mat0.flood_fill(point, 0, CvScalar.new(0), CvScalar.new(64)) + mat4, comp4, mask4 = mat0.flood_fill(point, 0, CvScalar.new(0), CvScalar.new(64), + {:connectivity => 8, :fixed_range => true, :mask_only => true}) + mat05 = mat0.clone + mat5, comp5, mask5 = mat05.flood_fill!(point, 0, CvScalar.new(0), CvScalar.new(64), + {:connectivity => 8, :fixed_range => true, :mask_only => true}) + + assert_equal(9216.0, comp1.area) + assert_equal(16, comp1.rect.x) + assert_equal(16, comp1.rect.y) + assert_equal(224, comp1.rect.width) + assert_equal(96, comp1.rect.height) + assert_cvscalar_equal(CvScalar.new(0, 0, 0, 0), comp1.value) + + assert_equal(20480.0, comp2.area) + assert_equal(0, comp2.rect.x) + assert_equal(0, comp2.rect.y) + assert_equal(256, comp2.rect.width) + assert_equal(128, comp2.rect.height) + assert_cvscalar_equal(CvScalar.new(0, 0, 0, 0), comp2.value) + + assert_equal(21504.0, comp3.area) + assert_equal(16, comp3.rect.x) + assert_equal(16, comp3.rect.y) + assert_equal(224, comp3.rect.width) + assert_equal(96, comp3.rect.height) + assert_cvscalar_equal(CvScalar.new(0, 0, 0, 0), comp3.value) + + assert_equal(21504.0, comp4.area) + assert_equal(16, comp4.rect.x) + assert_equal(16, comp4.rect.y) + assert_equal(224, comp4.rect.width) + assert_equal(96, comp4.rect.height) + assert_cvscalar_equal(CvScalar.new(228, 0, 0, 0), comp4.value) + + assert_equal(21504.0, comp5.area) + assert_equal(16, comp5.rect.x) + assert_equal(16, comp5.rect.y) + assert_equal(224, comp5.rect.width) + assert_equal(96, comp5.rect.height) + assert_cvscalar_equal(CvScalar.new(228, 0, 0, 0), comp5.value) + + assert_raise(TypeError) { + mat0.flood_fill(DUMMY_OBJ, 0) + } + assert_raise(TypeError) { + mat0.flood_fill(point, DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.flood_fill(point, 0, DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.flood_fill(point, 0, CvScalar.new(0), DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.flood_fill(point, 0, CvScalar.new(0), CvScalar.new(64), DUMMY_OBJ) + } + end + + def test_find_contours + mat0 = CvMat.load(FILENAME_CONTOURS, CV_LOAD_IMAGE_GRAYSCALE) + + # Make binary image + mat0.height.times { |j| + mat0.width.times { |i| + mat0[j, i] = (mat0[j, i][0] < 128) ? CvColor::Black : CvColor::White + } + } + + [mat0.find_contours, mat0.find_contours(:mode => CV_RETR_LIST), + mat0.find_contours(:method => CV_CHAIN_APPROX_SIMPLE), + mat0.find_contours(:mode => CV_RETR_LIST, :method => CV_CHAIN_APPROX_SIMPLE)].each { |contours| + assert_not_nil(contours) + assert_equal(8, contours.total) + assert_not_nil(contours.h_next) + assert_equal(4, contours.h_next.total) + assert_not_nil(contours.h_next.h_next) + assert_equal(8, contours.h_next.h_next.total) + assert_not_nil(contours.h_next.h_next.h_next) + assert_equal(4, contours.h_next.h_next.h_next.total) + assert_nil(contours.v_next) + assert_nil(contours.h_next.v_next) + assert_nil(contours.h_next.h_next.v_next) + assert_nil(contours.h_next.h_next.h_next.v_next) + } + + contours = mat0.find_contours(:mode => CV_RETR_TREE) + assert_not_nil(contours) + assert_equal(4, contours.total) + assert_not_nil(contours.v_next) + assert_equal(8, contours.v_next.total) + assert_nil(contours.v_next.v_next) + assert_not_nil(contours.h_next) + assert_equal(4, contours.h_next.total) + assert_not_nil(contours.h_next.v_next) + assert_equal(8, contours.h_next.v_next.total) + assert_nil(contours.h_next.v_next.v_next) + + contours = mat0.find_contours(:mode => CV_RETR_CCOMP) + assert_not_nil(contours) + assert_equal(4, contours.total) + assert_not_nil(contours.v_next) + assert_equal(8, contours.v_next.total) + assert_nil(contours.v_next.v_next) + assert_not_nil(contours.h_next) + assert_equal(4, contours.h_next.total) + assert_not_nil(contours.h_next.v_next) + assert_equal(8, contours.h_next.v_next.total) + assert_nil(contours.h_next.v_next.v_next) + + contours = mat0.find_contours(:mode => CV_RETR_EXTERNAL) + assert_not_nil(contours) + assert_equal(4, contours.total) + assert_nil(contours.v_next) + assert_not_nil(contours.h_next) + assert_equal(4, contours.h_next.total) + assert_nil(contours.h_next.v_next) + + contours = mat0.find_contours(:mode => CV_RETR_TREE, :method => CV_CHAIN_APPROX_NONE) + assert_not_nil(contours) + assert_equal(474, contours.total) + assert_not_nil(contours.v_next) + assert_equal(318, contours.v_next.total) + assert_nil(contours.v_next.v_next) + assert_not_nil(contours.h_next) + assert_equal(396, contours.h_next.total) + assert_not_nil(contours.h_next.v_next) + assert_equal(240, contours.h_next.v_next.total) + assert_nil(contours.h_next.v_next.v_next) + + contours = mat0.find_contours(:mode => CV_RETR_EXTERNAL, :method => CV_CHAIN_CODE) + assert_equal(474, contours.total) + assert_equal(396, contours.h_next.total) + + contours = mat0.find_contours(:mode => CV_RETR_EXTERNAL, :method => CV_CHAIN_APPROX_TC89_L1) + assert_equal(4, contours.total) + assert_equal(4, contours.h_next.total) + + contours = mat0.find_contours(:mode => CV_RETR_EXTERNAL, :method => CV_CHAIN_APPROX_TC89_KCOS) + assert_equal(4, contours.total) + assert_equal(4, contours.h_next.total) + + assert_raise(TypeError) { + mat0.find_contours(DUMMY_OBJ) + } + assert_raise(CvStsUnsupportedFormat) { + CvMat.new(10, 10, :cv32f, 3).find_contours + } + end + + def test_pyr_mean_shift_filtering + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + mat1 = mat0.pyr_mean_shift_filtering(30, 30) + mat2 = mat0.pyr_mean_shift_filtering(30, 30, 2) + mat3 = mat0.pyr_mean_shift_filtering(30, 30, nil, CvTermCriteria.new(3, 0.01)) + + [mat1, mat2, mat3].each { |mat| + b, g, r = color_hists(mat) + assert_in_delta(6900000, b, 100000) + assert_in_delta(6500000, g, 100000) + assert_in_delta(11800000, r, 100000) + } + + assert_raise(TypeError) { + mat0.pyr_mean_shift_filtering(DUMMY_OBJ, 30) + } + assert_raise(TypeError) { + mat0.pyr_mean_shift_filtering(30, DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.pyr_mean_shift_filtering(30, 30, 2, DUMMY_OBJ) + } + end + + def test_watershed + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + marker = CvMat.new(mat0.cols, mat0.rows, :cv32s, 1).set_zero + marker[150, 150] = CvScalar.new(1, 1, 1, 1) + marker[210, 210] = CvScalar.new(2, 2, 2, 2) + marker[40, 90] = CvScalar.new(3, 3, 3, 3) + + mat1 = mat0.watershed(marker) + assert_equal('ee6bec03296039c8df1899d3edc4684e', hash_img(mat1)) + + assert_raise(TypeError) { + mat0.watershed(DUMMY_OBJ) + } + end + + def test_moments + mat = create_cvmat(128, 128, :cv8u, 1) { |j, i| + if j >= 32 and j < 96 and i >= 16 and i < 112 + CvScalar.new(0) + elsif j >= 16 and j < 112 and i >= 16 and i < 112 + CvScalar.new(128) + else + CvScalar.new(255) + end + } + + moments1 = mat.moments + moments2 = mat.moments(false) + moments3 = mat.moments(true) + + [moments1, moments2].each { |m| + assert_in_delta(2221056, m.spatial(0, 0), 0.1) + assert_in_delta(2221056, m.central(0, 0), 0.1) + assert_in_delta(1, m.normalized_central(0, 0), 0.1) + + hu_moments = m.hu + assert_equal(CvHuMoments, hu_moments.class) + assert_in_delta(0.001771, hu_moments.hu1, 0.000001) + hu_moments.to_a[1..7].each { |hu| + assert_in_delta(0.0, hu, 0.000001) + } + + center = m.gravity_center + assert_equal(CvPoint2D32f, center.class) + assert_in_delta(63.5, center.x, 0.001) + assert_in_delta(63.5, center.y, 0.001) + + assert_in_delta(0, m.angle, 0.001) + + assert_in_delta(2221056, m.m00, 0.001) + assert_in_delta(141037056, m.m10, 0.001) + assert_in_delta(141037056, m.m01, 0.001) + assert_in_delta(13157049856, m.m20, 0.001) + assert_in_delta(8955853056, m.m11, 0.001) + assert_in_delta(13492594176, m.m02, 0.001) + assert_in_delta(1369024659456, m.m30, 0.001) + assert_in_delta(835472665856, m.m21, 0.001) + assert_in_delta(856779730176, m.m12, 0.001) + assert_in_delta(1432945852416, m.m03, 0.001) + assert_in_delta(4201196800, m.mu20, 0.001) + assert_in_delta(0, m.mu11, 0.001) + assert_in_delta(4536741120, m.mu02, 0.001) + assert_in_delta(0, m.mu30, 0.001) + assert_in_delta(0, m.mu21, 0.001) + assert_in_delta(0, m.mu12, 0.001) + assert_in_delta(0, m.mu03, 0.001) + assert_in_delta(0.000671, m.inv_sqrt_m00, 0.000001) + } + + m = moments3 + assert_in_delta(10240, m.spatial(0, 0), 0.1) + assert_in_delta(10240, m.central(0, 0), 0.1) + assert_in_delta(1, m.normalized_central(0, 0), 0.1) + + hu_moments = m.hu + assert_equal(CvHuMoments, hu_moments.class) + assert_in_delta(0.361650, hu_moments.hu1, 0.000001) + assert_in_delta(0.000625, hu_moments.hu2, 0.000001) + hu_moments.to_a[2..7].each { |hu| + assert_in_delta(0.0, hu, 0.000001) + } + + center = m.gravity_center + assert_equal(CvPoint2D32f, center.class) + assert_in_delta(63.5, center.x, 0.001) + assert_in_delta(63.5, center.y, 0.001) + + assert_in_delta(0, m.angle, 0.001) + + assert_in_delta(10240, m.m00, 0.001) + assert_in_delta(650240, m.m10, 0.001) + assert_in_delta(650240, m.m01, 0.001) + assert_in_delta(58940416, m.m20, 0.001) + assert_in_delta(41290240, m.m11, 0.001) + assert_in_delta(61561856, m.m02, 0.001) + assert_in_delta(5984288768, m.m30, 0.001) + assert_in_delta(3742716416, m.m21, 0.001) + assert_in_delta(3909177856, m.m12, 0.001) + assert_in_delta(6483673088, m.m03, 0.001) + assert_in_delta(17650176, m.mu20, 0.001) + assert_in_delta(0, m.mu11, 0.001) + assert_in_delta(20271616, m.mu02, 0.001) + assert_in_delta(0, m.mu30, 0.001) + assert_in_delta(0, m.mu21, 0.001) + assert_in_delta(0, m.mu12, 0.001) + assert_in_delta(0, m.mu03, 0.001) + assert_in_delta(0.009882, m.inv_sqrt_m00, 0.000001) + end + + def test_hough_lines + mat0 = CvMat.load(FILENAME_LINES, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + # make a binary image + mat = CvMat.new(mat0.rows, mat0.cols, :cv8u, 1) + (mat0.rows * mat0.cols).times { |i| + mat[i] = (mat0[i][0] <= 100) ? CvScalar.new(0) : CvScalar.new(255); + } + + [CV_HOUGH_STANDARD, :standard].each { |method| + seq = mat.hough_lines(method, 1, Math::PI / 180, 65) + assert_equal(4, seq.size) + } + + [CV_HOUGH_PROBABILISTIC, :probabilistic].each { |method| + seq = mat.hough_lines(method, 1, Math::PI / 180, 40, 30, 10) + assert_equal(4, seq.size) + } + + # [CV_HOUGH_MULTI_SCALE, :multi_scale].each { |method| + # seq = mat.hough_lines(method, 1, Math::PI / 180, 40, 2, 3) + # assert_equal(9, seq.size) + # } + + assert_raise(TypeError) { + mat.hough_lines(DUMMY_OBJ, 1, Math::PI / 180, 40, 2, 3) + } + assert_raise(TypeError) { + mat.hough_lines(CV_HOUGH_STANDARD, DUMMY_OBJ, Math::PI / 180, 40, 2, 3) + } + assert_raise(TypeError) { + mat.hough_lines(CV_HOUGH_STANDARD, 1, DUMMY_OBJ, 40, 2, 3) + } + assert_raise(TypeError) { + mat.hough_lines(CV_HOUGH_STANDARD, 1, Math::PI / 180, DUMMY_OBJ, 2, 3) + } + assert_raise(TypeError) { + mat.hough_lines(CV_HOUGH_STANDARD, 1, Math::PI / 180, 40, DUMMY_OBJ, 3) + } + assert_raise(TypeError) { + mat.hough_lines(CV_HOUGH_STANDARD, 1, Math::PI / 180, 40, 2, DUMMY_OBJ) + } + assert_raise(ArgumentError) { + mat.hough_lines(:dummy, 1, Math::PI / 180, 40, 2, DUMMY_OBJ) + } + assert_raise(CvStsBadArg) { + CvMat.new(10, 10, :cv32f, 3).hough_lines(:standard, 1, Math::PI / 180, 65) + } + end + + def test_hough_circles + mat0 = CvMat.load(FILENAME_LINES, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + # make a binary image + mat = CvMat.new(mat0.rows, mat0.cols, :cv8u, 1) + (mat0.rows * mat0.cols).times { |i| + mat[i] = (mat0[i][0] <= 100) ? CvScalar.new(0) : CvScalar.new(255); + } + + [mat.hough_circles(CV_HOUGH_GRADIENT, 1.5, 40, 100, 40, 10, 50), + mat.hough_circles(:gradient, 1.5, 40, 100, 40, 10, 50), + mat.hough_circles(CV_HOUGH_GRADIENT, 1.5, 40, 100, 40), + mat.hough_circles(:gradient, 1.5, 40, 100, 40)].each { |seq| + assert_equal(2, seq.size) + } + + # Uncomment the following lines to show the result + # seq = mat.hough_circles(:gradient, 1.5, 40, 100, 40, 10, 50) + # seq.each { |circle| + # mat0.circle!(circle.center, circle.radius, :color => CvColor::Red, :thickness => 2) + # } + # snap mat0 + + assert_raise(TypeError) { + mat.hough_circles(DUMMY_OBJ, 1.5, 40, 100, 50, 10, 50) + } + assert_raise(TypeError) { + mat.hough_circles(CV_HOUGH_GRADIENT, DUMMY_OBJ, 40, 100, 50, 10, 50) + } + assert_raise(TypeError) { + mat.hough_circles(CV_HOUGH_GRADIENT, 1.5, DUMMY_OBJ, 100, 50, 10, 50) + } + assert_raise(TypeError) { + mat.hough_circles(CV_HOUGH_GRADIENT, 1.5, 40, DUMMY_OBJ, 50, 10, 50) + } + assert_raise(TypeError) { + mat.hough_circles(CV_HOUGH_GRADIENT, 1.5, 40, 100, DUMMY_OBJ, 10, 50) + } + assert_raise(TypeError) { + mat.hough_circles(CV_HOUGH_GRADIENT, 1.5, 40, 100, 50, DUMMY_OBJ, 50) + } + assert_raise(TypeError) { + mat.hough_circles(CV_HOUGH_GRADIENT, 1.5, 40, 100, 50, 10, DUMMY_OBJ) + } + assert_raise(ArgumentError) { + mat.hough_circles(:dummy, 1.5, 40, 100, 50, 10, DUMMY_OBJ) + } + assert_raise(CvStsBadArg) { + CvMat.new(10, 10, :cv32f, 3).hough_circles(:gradient, 1.5, 40, 100, 50, 10, 50) + } + end + + def test_inpaint + mat = CvMat.load(FILENAME_LENA_INPAINT, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + mask = CvMat.load(FILENAME_INPAINT_MASK, CV_LOAD_IMAGE_GRAYSCALE) + + [CV_INPAINT_NS, :ns].each { |method| + result_ns = mat.inpaint(method, mask, 10) + assert_in_delta(14000, count_threshold(result_ns, 128), 1000) + } + [CV_INPAINT_TELEA, :telea].each { |method| + result_telea = mat.inpaint(method, mask, 10) + assert_in_delta(13500, count_threshold(result_telea, 128), 1000) + } + + # Uncomment the following lines to show the results + # result_ns = mat.inpaint(:ns, mask, 10) + # result_telea = mat.inpaint(:telea, mask, 10) + # snap mat, result_ns, result_telea + + assert_raise(TypeError) { + mat.inpaint(DUMMY_OBJ, mask, 10) + } + assert_raise(TypeError) { + mat.inpaint(:ns, DUMMY_OBJ, 10) + } + assert_raise(TypeError) { + mat.inpaint(:ns, mask, DUMMY_OBJ) + } + assert_raise(ArgumentError) { + mat.inpaint(:dummy, mask, 10) + } + assert_raise(CvStsUnsupportedFormat) { + CvMat.new(10, 10, :cv32f, 3).inpaint(:ns, CvMat.new(10, 10, :cv8u, 1), 10) + } + end + + def test_equalize_hist + mat = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_GRAYSCALE) + result = mat.equalize_hist + assert_equal(CvMat, result.class) + assert_equal(mat.rows, result.rows) + assert_equal(mat.cols, result.cols) + + assert_raise(CvStsAssert) { + CvMat.new(10, 10, :cv32f, 3).equalize_hist + } + + # Uncomment the following lines to show the result + # snap mat, result + end + + def test_match_template + mat = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + templ = CvMat.load(FILENAME_LENA_EYES, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + + expected_pt = CvPoint.new(100, 120) + + # sqdiff + result = mat.match_template(templ) + pt = result.min_max_loc[2] + assert_in_delta(expected_pt.x, pt.x, 20) + assert_in_delta(expected_pt.y, pt.y, 20) + + [CV_TM_SQDIFF, :sqdiff].each { |method| + result = mat.match_template(templ, method) + assert_in_delta(expected_pt.x, pt.x, 20) + assert_in_delta(expected_pt.y, pt.y, 20) + } + + # sqdiff_normed + [CV_TM_SQDIFF_NORMED, :sqdiff_normed].each { |method| + result = mat.match_template(templ, method) + pt = result.min_max_loc[2] + assert_in_delta(expected_pt.x, pt.x, 20) + assert_in_delta(expected_pt.y, pt.y, 20) + } + + # ccorr + [CV_TM_CCORR, :ccorr].each { |method| + result = mat.match_template(templ, method) + pt = result.min_max_loc[3] + assert_in_delta(110, pt.x, 20) + assert_in_delta(60, pt.y, 20) + } + + # ccorr_normed + [CV_TM_CCORR_NORMED, :ccorr_normed].each { |method| + result = mat.match_template(templ, method) + pt = result.min_max_loc[3] + assert_in_delta(expected_pt.x, pt.x, 20) + assert_in_delta(expected_pt.y, pt.y, 20) + } + + # ccoeff + [CV_TM_CCOEFF, :ccoeff].each { |method| + result = mat.match_template(templ, method) + pt = result.min_max_loc[3] + assert_in_delta(expected_pt.x, pt.x, 20) + assert_in_delta(expected_pt.y, pt.y, 20) + } + + # ccoeff_normed + [CV_TM_CCOEFF_NORMED, :ccoeff_normed].each { |method| + result = mat.match_template(templ, method) + pt = result.min_max_loc[3] + assert_in_delta(expected_pt.x, pt.x, 20) + assert_in_delta(expected_pt.y, pt.y, 20) + } + + # Uncomment the following lines to show the result + # result = mat.match_template(templ) + # pt1 = result.min_max_loc[2] # minimum location + # pt2 = CvPoint.new(pt1.x + templ.width, pt1.y + templ.height) + # mat.rectangle!(pt1, pt2, :color => CvColor::Black, :thickness => 3) + # snap mat, templ, result + + assert_raise(TypeError) { + mat.match_template(DUMMY_OBJ) + } + assert_raise(TypeError) { + mat.match_template(templ, DUMMY_OBJ) + } + end + + def test_match_shapes + mat_cv = CvMat.load(FILENAME_STR_CV, CV_LOAD_IMAGE_GRAYSCALE) + mat_ov = CvMat.load(FILENAME_STR_OV, CV_LOAD_IMAGE_GRAYSCALE) + mat_cv_rotated = CvMat.load(FILENAME_STR_CV_ROTATED, CV_LOAD_IMAGE_GRAYSCALE) + + [CV_CONTOURS_MATCH_I1, :i1].each { |method| + assert_in_delta(0, mat_cv.match_shapes(mat_cv_rotated, method), 0.00001) + assert_in_delta(0.0010649, mat_cv.match_shapes(mat_ov, method), 0.00001) + } + + [CV_CONTOURS_MATCH_I2, :i2].each { |method| + assert_in_delta(0, mat_cv.match_shapes(mat_cv_rotated, method), 0.00001) + assert_in_delta(0.0104650, mat_cv.match_shapes(mat_ov, method), 0.00001) + } + + [CV_CONTOURS_MATCH_I3, :i3].each { |method| + assert_in_delta(0, mat_cv.match_shapes(mat_cv_rotated, method), 0.00001) + assert_in_delta(0.0033327, mat_cv.match_shapes(mat_ov, method), 0.00001) + } + end + + def test_mean_shift + flunk('FIXME: CvMat#mean_shift is not tested yet.') + end + + def test_cam_shift + flunk('FIXME: CvMat#cam_shift is not tested yet.') + end + + def test_snake_image + radius = 40 + center = CvPoint.new(128, 128) + mat = CvMat.new(center.y * 2, center.x * 2, :cv8u, 1).zero! + mat.circle!(center, radius, :color => CvColor::White, :thickness => -1) + + num_points = 10 + alpha = 0.05 + beta = 0.05 + gamma = 0.9 + + arr_alpha = [alpha] * num_points + arr_beta = [beta] * num_points + arr_gamma = [gamma] * num_points + size = CvSize.new(3, 3) + term_criteria = CvTermCriteria.new(100, num_points / 2) + + # initialize contours + points = [] + num_points.times { |i| + x = center.x * Math.cos(2 * Math::PI * i / num_points) + center.x + y = center.y * Math.sin(2 * Math::PI * i / num_points) + center.y + points << CvPoint.new(x, y) + } + + acceptable_error = 50 + + # test snake_image + # calc_gradient = true + [mat.snake_image(points, alpha, beta, gamma, size, term_criteria), + mat.snake_image(points, alpha, beta, gamma, size, term_criteria, true), + mat.snake_image(points, arr_alpha, arr_beta, arr_gamma, size, term_criteria), + mat.snake_image(points, arr_alpha, arr_beta, arr_gamma, size, term_criteria, true)].each { |result| + assert_equal(num_points, result.size) + result.each { |pt| + x = pt.x - center.x + y = pt.y - center.y + error = Math.sqrt((x * x + y * y - radius * radius).abs) + assert(error < acceptable_error) + } + } + + # calc_gradient = false + [mat.snake_image(points, alpha, beta, gamma, size, term_criteria, false), + mat.snake_image(points, arr_alpha, arr_beta, arr_gamma, size, term_criteria, false)].each { |result| + expected_points = [[149, 102], [139, 144], [95, 144], [56, 124], [17, 105], + [25, 61], [63, 39], [101, 17], [145, 17], [158, 59]] + assert_equal(num_points, result.size) + result.each { |pt| + x = pt.x - center.x + y = pt.y - center.y + error = Math.sqrt((x * x + y * y - radius * radius).abs) + assert(error < acceptable_error) + } + } + + # raise error + assert_raise(TypeError) { + mat.snake_image(DUMMY_OBJ, arr_alpha, arr_beta, arr_gamma, size, term_criteria) + } + assert_raise(TypeError) { + mat.snake_image(points, DUMMY_OBJ, arr_beta, arr_gamma, size, term_criteria) + } + assert_raise(TypeError) { + mat.snake_image(points, arr_alpha, DUMMY_OBJ, arr_gamma, size, term_criteria) + } + assert_raise(TypeError) { + mat.snake_image(points, arr_alpha, arr_beta, DUMMY_OBJ, size, term_criteria) + } + assert_raise(TypeError) { + mat.snake_image(points, arr_alpha, arr_beta, arr_gamma, DUMMY_OBJ, term_criteria) + } + assert_raise(TypeError) { + mat.snake_image(points, arr_alpha, arr_beta, arr_gamma, size, DUMMY_OBJ) + } + mat.snake_image(points, arr_alpha, arr_beta, arr_gamma, size, term_criteria, DUMMY_OBJ) + + assert_raise(ArgumentError) { + mat.snake_image(points, arr_alpha[0 .. num_points / 2], arr_beta, arr_gamma, size, term_criteria) + } + assert_raise(CvBadNumChannels) { + CvMat.new(10, 10, :cv8u, 3).snake_image(points, alpha, beta, gamma, size, term_criteria) + } + + # Uncomment the following lines to show the result + # result = mat.clone.GRAY2BGR + # pts = mat.snake_image(points, alpha, beta, gamma, size, term_criteria) + # w = GUI::Window.new('HoughCircle') + # result.poly_line!([pts], :color => CvColor::Red, :is_closed => true, :thickness => 2) + # result.poly_line!([points], :color => CvColor::Yellow, :is_closed => true, :thickness => 2) + # w.show result + # GUI::wait_key + end + + def test_optical_flow_hs + size = 128 + prev = create_cvmat(size, size, :cv8u, 1) { |j, i| + if ((i - (size / 2)) ** 2 ) + ((j - (size / 2)) ** 2 ) < size + CvColor::Black + else + CvColor::White + end + } + curr = create_cvmat(size, size, :cv8u, 1) { |j, i| + if ((i - (size / 2) - 10) ** 2) + ((j - (size / 2) - 7) ** 2 ) < size + CvColor::Black + else + CvColor::White + end + } + + [curr.optical_flow_hs(prev, nil, nil, :lambda => 0.0005, :criteria => CvTermCriteria.new(1, 0.001)), + curr.optical_flow_hs(prev)].each { |velx, vely| + assert_in_delta(60, count_threshold(velx, 1), 20) + assert_in_delta(50, count_threshold(vely, 1), 20) + } + + velx, vely = curr.optical_flow_hs(prev, nil, nil, :lambda => 0.001) + assert_in_delta(60, count_threshold(velx, 1), 20) + assert_in_delta(50, count_threshold(vely, 1), 20) + + velx, vely = curr.optical_flow_hs(prev, nil, nil, :criteria => CvTermCriteria.new(10, 0.01)) + assert_in_delta(130, count_threshold(velx, 1), 20) + assert_in_delta(110, count_threshold(vely, 1), 20) + + prev_velx, prev_vely = curr.optical_flow_hs(prev) + velx, vely = curr.optical_flow_hs(prev, prev_velx, prev_vely) + assert_in_delta(70, count_threshold(velx, 1), 20) + assert_in_delta(60, count_threshold(vely, 1), 20) + + velx, vely = curr.optical_flow_hs(prev, prev_velx, prev_vely, :lambda => 0.001) + assert_in_delta(80, count_threshold(velx, 1), 20) + assert_in_delta(70, count_threshold(vely, 1), 20) + + velx, vely = curr.optical_flow_hs(prev, prev_velx, prev_vely, :criteria => CvTermCriteria.new(10, 0.01)) + assert_in_delta(150, count_threshold(velx, 1), 20) + assert_in_delta(130, count_threshold(vely, 1), 20) + + assert_raise(TypeError) { + curr.optical_flow_hs(DUMMY_OBJ) + } + assert_raise(TypeError) { + curr.optical_flow_hs(prev, DUMMY_OBJ, prev_vely) + } + assert_raise(TypeError) { + curr.optical_flow_hs(prev, prev_velx, DUMMY_OBJ) + } + assert_raise(TypeError) { + curr.optical_flow_hs(prev, prev_velx, prev_vely, DUMMY_OBJ) + } + assert_raise(CvStsUnmatchedFormats) { + CvMat.new(10, 10, :cv8u, 3).optical_flow_hs(prev) + } + end + + def test_optical_flow_lk + size = 128 + prev = create_cvmat(size, size, :cv8u, 1) { |j, i| + if ((i - (size / 2)) ** 2 ) + ((j - (size / 2)) ** 2 ) < size + CvColor::Black + else + CvColor::White + end + } + curr = create_cvmat(size, size, :cv8u, 1) { |j, i| + if ((i - (size / 2) - 10) ** 2) + ((j - (size / 2) - 7) ** 2 ) < size + CvColor::Black + else + CvColor::White + end + } + + velx, vely = curr.optical_flow_lk(prev, CvSize.new(3, 3)) + assert_in_delta(100, count_threshold(velx, 1), 20) + assert_in_delta(90, count_threshold(vely, 1), 20) + + velx, vely = curr.optical_flow_lk(prev, CvSize.new(5, 5)) + assert_in_delta(180, count_threshold(velx, 1), 20) + assert_in_delta(150, count_threshold(vely, 1), 20) + + assert_raise(TypeError) { + curr.optical_flow_lk(DUMMY_OBJ, CvSize.new(3, 3)) + } + assert_raise(TypeError) { + curr.optical_flow_lk(prev, DUMMY_OBJ) + } + assert_raise(CvStsUnmatchedFormats) { + CvMat.new(10, 10, :cv8u, 3).optical_flow_lk(prev, CvSize.new(3, 3)) + } + end + + def test_optical_flow_bm + size = 128 + prev = create_cvmat(size, size, :cv8u, 1) { |j, i| + if ((i - (size / 2)) ** 2 ) + ((j - (size / 2)) ** 2 ) < size + CvColor::Black + else + CvColor::White + end + } + curr = create_cvmat(size, size, :cv8u, 1) { |j, i| + if ((i - (size / 2) - 10) ** 2) + ((j - (size / 2) - 7) ** 2 ) < size + CvColor::Black + else + CvColor::White + end + } + + [curr.optical_flow_bm(prev, nil, nil, :block_size => CvSize.new(4, 4), + :shift_size => CvSize.new(1, 1), :max_range => CvSize.new(4, 4)), + curr.optical_flow_bm(prev)].each { |velx, vely| + assert_in_delta(350, count_threshold(velx, 1), 30) + assert_in_delta(250, count_threshold(vely, 1), 30) + } + + velx, vely = curr.optical_flow_bm(prev, nil, nil, :block_size => CvSize.new(3, 3)) + assert_in_delta(280, count_threshold(velx, 1), 30) + assert_in_delta(200, count_threshold(vely, 1), 30) + + velx, vely = curr.optical_flow_bm(prev, nil, nil, :shift_size => CvSize.new(2, 2)) + assert_in_delta(80, count_threshold(velx, 1), 30) + assert_in_delta(60, count_threshold(vely, 1), 30) + + velx, vely = curr.optical_flow_bm(prev, nil, nil, :max_range => CvSize.new(5, 5)) + assert_in_delta(400, count_threshold(velx, 1), 30) + assert_in_delta(300, count_threshold(vely, 1), 30) + + prev_velx, prev_vely = curr.optical_flow_bm(prev) + velx, vely = curr.optical_flow_bm(prev, prev_velx, prev_vely) + assert_in_delta(350, count_threshold(velx, 1), 30) + assert_in_delta(270, count_threshold(vely, 1), 30) + + assert_raise(TypeError) { + curr.optical_flow_bm(DUMMY_OBJ) + } + assert_raise(TypeError) { + curr.optical_flow_bm(prev, DUMMY_OBJ, prev_vely) + } + assert_raise(TypeError) { + curr.optical_flow_bm(prev, prev_velx, DUMMY_OBJ) + } + assert_raise(TypeError) { + curr.optical_flow_bm(prev, prev_velx, prev_vely, DUMMY_OBJ) + } + assert_raise(CvStsUnmatchedFormats) { + CvMat.new(10, 10, :cv8u, 3).optical_flow_bm(prev) + } + end + + def test_extract_surf + mat0 = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_GRAYSCALE) + + # simple + keypoints1, descriptors1 = mat0.extract_surf(CvSURFParams.new(500, true, 2, 3)) + assert_equal(CvSeq, keypoints1.class) + assert_equal(254, keypoints1.size) + assert_equal(Array, descriptors1.class) + assert_equal(254, descriptors1.size) + assert_equal(Array, descriptors1[0].class) + assert_equal(128, descriptors1[0].size) + + # use mask + mask = create_cvmat(mat0.rows, mat0.cols, :cv8u, 1) { |j, i| + if i < mat0.cols / 2 + CvScalar.new(1) + else + CvScalar.new(0) + end + } + keypoints2, descriptors2 = mat0.extract_surf(CvSURFParams.new(500, false), mask) + assert_equal(CvSeq, keypoints2.class) + assert_equal(170, keypoints2.size) + assert_equal(Array, descriptors2.class) + assert_equal(170, descriptors2.size) + assert_equal(Array, descriptors2[0].class) + assert_equal(64, descriptors2[0].size) + + # raise exceptions because of invalid arguments + assert_raise(TypeError) { + mat0.extract_surf(DUMMY_OBJ) + } + assert_raise(TypeError) { + mat0.extract_surf(CvSURFParams.new(500), DUMMY_OBJ) + } + + # Uncomment the following lines to show the result + # results = [] + # [keypoints1, keypoints2].each { |kpts| + # tmp = mat0.GRAY2BGR + # kpts.each { |kp| + # tmp.circle!(kp.pt, 3, :color => CvColor::Red, :thickness => 1, :line_type => :aa) + # } + # results << tmp + # } + # snap mat0, *results + end +end + diff --git a/test/test_cvmoments.rb b/test/test_cvmoments.rb new file mode 100755 index 00000000..c5d3c767 --- /dev/null +++ b/test/test_cvmoments.rb @@ -0,0 +1,180 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvMoment +class TestCvMoments < OpenCVTestCase + def setup + @mat = create_cvmat(128, 128, :cv8u, 1) { |j, i| + if j >= 32 and j < 96 and i >= 16 and i < 112 + CvScalar.new(0) + elsif j >= 16 and j < 112 and i >= 16 and i < 112 + CvScalar.new(128) + else + CvScalar.new(255) + end + } + @moment1 = CvMoments.new + @moment2 = CvMoments.new(nil, true) + @moment3 = CvMoments.new(@mat) + @moment4 = CvMoments.new(@mat, true) + end + + def test_initialize + [@moment1, @moment2, @moment3, @moment4].each { |m| + assert_not_nil(m) + assert_equal(CvMoments, m.class) + } + + assert_raise(TypeError) { + CvMoments.new('foo') + } + end + + def test_spatial + assert_in_delta(0, @moment1.spatial(0, 0), 0.1) + assert_in_delta(0, @moment2.spatial(0, 0), 0.1) + assert_in_delta(2221056, @moment3.spatial(0, 0), 0.1) + assert_in_delta(10240, @moment4.spatial(0, 0), 0.1) + end + + def test_central + assert_in_delta(0, @moment1.central(0, 0), 0.1) + assert_in_delta(0, @moment2.central(0, 0), 0.1) + assert_in_delta(2221056, @moment3.central(0, 0), 0.1) + assert_in_delta(10240, @moment4.central(0, 0), 0.1) + end + + def test_normalized_central + assert_in_delta(0, @moment1.normalized_central(0, 0), 0.1) + assert_in_delta(0, @moment2.normalized_central(0, 0), 0.1) + assert_in_delta(1, @moment3.normalized_central(0, 0), 0.1) + assert_in_delta(1, @moment4.normalized_central(0, 0), 0.1) + end + + def test_hu + hu_moments = @moment1.hu + assert_equal(CvHuMoments, hu_moments.class) + hu_moments.to_a.each { |hu| + assert_in_delta(0.0, hu, 0.000001) + } + + hu_moments = @moment2.hu + assert_equal(CvHuMoments, hu_moments.class) + hu_moments.to_a.each { |hu| + assert_in_delta(0.0, hu, 0.000001) + } + + hu_moments = @moment3.hu + assert_equal(CvHuMoments, hu_moments.class) + assert_in_delta(0.001771, hu_moments.hu1, 0.000001) + hu_moments.to_a[1..7].each { |hu| + assert_in_delta(0.0, hu, 0.000001) + } + + hu_moments = @moment4.hu + assert_equal(CvHuMoments, hu_moments.class) + assert_in_delta(0.361650, hu_moments.hu1, 0.000001) + assert_in_delta(0.000625, hu_moments.hu2, 0.000001) + hu_moments.to_a[2..7].each { |hu| + assert_in_delta(0.0, hu, 0.000001) + } + end + + def test_gravity_center + center = @moment1.gravity_center + assert_equal(CvPoint2D32f, center.class) + assert(center.x.nan?) + assert(center.y.nan?) + + center = @moment2.gravity_center + assert_equal(CvPoint2D32f, center.class) + assert(center.x.nan?) + assert(center.y.nan?) + + center = @moment3.gravity_center + assert_equal(CvPoint2D32f, center.class) + assert_in_delta(63.5, center.x, 0.001) + assert_in_delta(63.5, center.y, 0.001) + + center = @moment4.gravity_center + assert_equal(CvPoint2D32f, center.class) + assert_in_delta(63.5, center.x, 0.001) + assert_in_delta(63.5, center.y, 0.001) + end + + def test_angle + [@moment1, @moment2].each { |m| + assert_nil(m.angle) + } + [@moment3, @moment4].each { |m| + assert_in_delta(0, m.angle, 0.001) + } + end + + def test_mXX + [@moment1, @moment2].each { |m| + assert_in_delta(0, m.m00, 0.001) + assert_in_delta(0, m.m10, 0.001) + assert_in_delta(0, m.m01, 0.001) + assert_in_delta(0, m.m20, 0.001) + assert_in_delta(0, m.m11, 0.001) + assert_in_delta(0, m.m02, 0.001) + assert_in_delta(0, m.m30, 0.001) + assert_in_delta(0, m.m21, 0.001) + assert_in_delta(0, m.m12, 0.001) + assert_in_delta(0, m.m03, 0.001) + assert_in_delta(0, m.mu20, 0.001) + assert_in_delta(0, m.mu11, 0.001) + assert_in_delta(0, m.mu02, 0.001) + assert_in_delta(0, m.mu30, 0.001) + assert_in_delta(0, m.mu21, 0.001) + assert_in_delta(0, m.mu12, 0.001) + assert_in_delta(0, m.mu03, 0.001) + assert_in_delta(0, m.inv_sqrt_m00, 0.001) + } + + assert_in_delta(2221056, @moment3.m00, 0.001) + assert_in_delta(141037056, @moment3.m10, 0.001) + assert_in_delta(141037056, @moment3.m01, 0.001) + assert_in_delta(13157049856, @moment3.m20, 0.001) + assert_in_delta(8955853056, @moment3.m11, 0.001) + assert_in_delta(13492594176, @moment3.m02, 0.001) + assert_in_delta(1369024659456, @moment3.m30, 0.001) + assert_in_delta(835472665856, @moment3.m21, 0.001) + assert_in_delta(856779730176, @moment3.m12, 0.001) + assert_in_delta(1432945852416, @moment3.m03, 0.001) + assert_in_delta(4201196800, @moment3.mu20, 0.001) + assert_in_delta(0, @moment3.mu11, 0.001) + assert_in_delta(4536741120, @moment3.mu02, 0.001) + assert_in_delta(0, @moment3.mu30, 0.001) + assert_in_delta(0, @moment3.mu21, 0.001) + assert_in_delta(0, @moment3.mu12, 0.001) + assert_in_delta(0, @moment3.mu03, 0.001) + assert_in_delta(0.000671, @moment3.inv_sqrt_m00, 0.000001) + + assert_in_delta(10240, @moment4.m00, 0.001) + assert_in_delta(650240, @moment4.m10, 0.001) + assert_in_delta(650240, @moment4.m01, 0.001) + assert_in_delta(58940416, @moment4.m20, 0.001) + assert_in_delta(41290240, @moment4.m11, 0.001) + assert_in_delta(61561856, @moment4.m02, 0.001) + assert_in_delta(5984288768, @moment4.m30, 0.001) + assert_in_delta(3742716416, @moment4.m21, 0.001) + assert_in_delta(3909177856, @moment4.m12, 0.001) + assert_in_delta(6483673088, @moment4.m03, 0.001) + assert_in_delta(17650176, @moment4.mu20, 0.001) + assert_in_delta(0, @moment4.mu11, 0.001) + assert_in_delta(20271616, @moment4.mu02, 0.001) + assert_in_delta(0, @moment4.mu30, 0.001) + assert_in_delta(0, @moment4.mu21, 0.001) + assert_in_delta(0, @moment4.mu12, 0.001) + assert_in_delta(0, @moment4.mu03, 0.001) + assert_in_delta(0.009882, @moment4.inv_sqrt_m00, 0.000001) + end +end + diff --git a/test/test_cvpoint.rb b/test/test_cvpoint.rb new file mode 100755 index 00000000..14a801ce --- /dev/null +++ b/test/test_cvpoint.rb @@ -0,0 +1,75 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvPoint +class TestCvPoint < OpenCVTestCase + class MyPoint; end + def test_x + point = CvPoint.new + point.x = 100 + assert_equal(100, point.x) + point.x = 200 + assert_equal(200, point.x) + end + + def test_y + point = CvPoint.new + point.y = 100 + assert_equal(100, point.y) + point.y = 200 + assert_equal(200, point.y) + end + + def test_compatible + assert(!(CvPoint.compatible? MyPoint.new)) + MyPoint.class_eval { def x; end } + assert(!(CvPoint.compatible? MyPoint.new)) + MyPoint.class_eval { def y; end } + assert(CvPoint.compatible? MyPoint.new) + assert(CvPoint.compatible? CvPoint.new) + end + + def test_initialize + point = CvPoint.new + assert_equal(0, point.x) + assert_equal(0, point.y) + + point = CvPoint.new(10, 20) + assert_equal(10, point.x) + assert_equal(20, point.y) + + point = CvPoint.new(CvPoint.new(10, 20)) + assert_equal(10, point.x) + assert_equal(20, point.y) + + assert_raise(TypeError) { + CvPoint.new(DUMMY_OBJ) + } + assert_raise(ArgumentError) { + CvPoint.new(1, 2, 3) + } + end + + def test_to_s + point = CvPoint.new(10, 20) + assert_equal('', point.to_s) + end + + def test_to_ary + a = CvPoint.new(10, 20).to_ary + assert_equal(10, a[0]) + assert_equal(20, a[1]) + + # Alias + a = CvPoint.new(10, 20).to_a + assert_equal(10, a[0]) + assert_equal(20, a[1]) + end +end + + diff --git a/test/test_cvpoint2d32f.rb b/test/test_cvpoint2d32f.rb new file mode 100755 index 00000000..e78eb43e --- /dev/null +++ b/test/test_cvpoint2d32f.rb @@ -0,0 +1,75 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvPoint2D32f +class TestCvPoint2D32f < OpenCVTestCase + class MyPoint; end + def test_x + point = CvPoint2D32f.new + point.x = 1.1 + assert_in_delta(1.1, point.x, 0.001) + point.x = 2.2 + assert_in_delta(2.2, point.x, 0.001) + end + + def test_y + point = CvPoint2D32f.new + point.y = 1.1 + assert_in_delta(1.1, point.y, 0.001) + point.y = 2.2 + assert_in_delta(2.2, point.y, 0.001) + end + + def test_compatible + assert(!(CvPoint2D32f.compatible? MyPoint.new)) + MyPoint.class_eval { def x; end } + assert(!(CvPoint2D32f.compatible? MyPoint.new)) + MyPoint.class_eval { def y; end } + assert(CvPoint2D32f.compatible? MyPoint.new) + assert(CvPoint2D32f.compatible? CvPoint2D32f.new) + end + + def test_initialize + point = CvPoint2D32f.new + assert_in_delta(0, point.x, 0.001) + assert_in_delta(0, point.y, 0.001) + + point = CvPoint2D32f.new(1.1, 2.2) + assert_in_delta(1.1, point.x, 0.001) + assert_in_delta(2.2, point.y, 0.001) + + point = CvPoint2D32f.new(CvPoint2D32f.new(1.1, 2.2)) + assert_in_delta(1.1, point.x, 0.001) + assert_in_delta(2.2, point.y, 0.001) + + assert_raise(TypeError) { + CvPoint2D32f.new(DUMMY_OBJ) + } + assert_raise(ArgumentError) { + CvPoint2D32f.new(1, 2, 3) + } + end + + def test_to_s + point = CvPoint2D32f.new(1.1, 2.2) + assert_equal('', point.to_s) + end + + def test_to_ary + a = CvPoint2D32f.new(1.1, 2.2).to_ary + assert_in_delta(1.1, a[0], 0.001) + assert_in_delta(2.2, a[1], 0.001) + + # Alias + a = CvPoint2D32f.new(1.1, 2.2).to_a + assert_in_delta(1.1, a[0], 0.001) + assert_in_delta(2.2, a[1], 0.001) + end +end + + diff --git a/test/test_cvpoint3d32f.rb b/test/test_cvpoint3d32f.rb new file mode 100755 index 00000000..2d2e680c --- /dev/null +++ b/test/test_cvpoint3d32f.rb @@ -0,0 +1,93 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvPoint3D32f +class TestCvPoint3D32f < OpenCVTestCase + class MyPoint; end + def test_x + point = CvPoint3D32f.new + point.x = 1.1 + assert_in_delta(1.1, point.x, 0.001) + point.x = 2.2 + assert_in_delta(2.2, point.x, 0.001) + end + + def test_y + point = CvPoint3D32f.new + point.y = 1.1 + assert_in_delta(1.1, point.y, 0.001) + point.y = 2.2 + assert_in_delta(2.2, point.y, 0.001) + end + + def test_z + point = CvPoint3D32f.new + point.z = 1.1 + assert_in_delta(1.1, point.z, 0.001) + point.z = 2.2 + assert_in_delta(2.2, point.z, 0.001) + end + + def test_compatible + assert(!(CvPoint3D32f.compatible? MyPoint.new)) + MyPoint.class_eval { def x; end } + assert(!(CvPoint3D32f.compatible? MyPoint.new)) + MyPoint.class_eval { def y; end } + assert(!(CvPoint3D32f.compatible? MyPoint.new)) + MyPoint.class_eval { def z; end } + assert(CvPoint3D32f.compatible? MyPoint.new) + assert(CvPoint3D32f.compatible? CvPoint3D32f.new) + end + + def test_initialize + point = CvPoint3D32f.new + assert_in_delta(0, point.x, 0.001) + assert_in_delta(0, point.y, 0.001) + assert_in_delta(0, point.z, 0.001) + + point = CvPoint3D32f.new(1.1, 2.2, 3.3) + assert_in_delta(1.1, point.x, 0.001) + assert_in_delta(2.2, point.y, 0.001) + assert_in_delta(3.3, point.z, 0.001) + + point = CvPoint3D32f.new(CvPoint3D32f.new(1.1, 2.2, 3.3)) + assert_in_delta(1.1, point.x, 0.001) + assert_in_delta(2.2, point.y, 0.001) + assert_in_delta(3.3, point.z, 0.001) + + assert_raise(TypeError) { + CvPoint3D32f.new(DUMMY_OBJ) + } + assert_raise(ArgumentError) { + CvPoint3D32f.new(1, 2) + } + assert_raise(ArgumentError) { + CvPoint3D32f.new(1, 2, 3, 4) + } + end + + def test_to_s + point = CvPoint3D32f.new(1.1, 2.2, 3.3) + assert_equal('', point.to_s) + end + + def test_to_ary + a = CvPoint3D32f.new(1.1, 2.2, 3.3).to_ary + assert_in_delta(1.1, a[0], 0.001) + assert_in_delta(2.2, a[1], 0.001) + assert_in_delta(3.3, a[2], 0.001) + + # Alias + a = CvPoint3D32f.new(1.1, 2.2, 3.3).to_a + assert_in_delta(1.1, a[0], 0.001) + assert_in_delta(2.2, a[1], 0.001) + assert_in_delta(3.3, a[2], 0.001) + end +end + + diff --git a/test/test_cvrect.rb b/test/test_cvrect.rb new file mode 100755 index 00000000..b144a2c3 --- /dev/null +++ b/test/test_cvrect.rb @@ -0,0 +1,144 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvRect +class TestCvRect < OpenCVTestCase + class MyRect; end + + def test_x + rect = CvRect.new + rect.x = 100 + assert_equal(100, rect.x) + rect.x = 200 + assert_equal(200, rect.x) + end + + def test_y + rect = CvRect.new + rect.y = 100 + assert_equal(100, rect.y) + rect.y = 200 + assert_equal(200, rect.y) + end + + def test_width + rect = CvRect.new + rect.width = 100 + assert_equal(100, rect.width) + rect.width = 200 + assert_equal(200, rect.width) + end + + def test_height + rect = CvRect.new + rect.height = 100 + assert_equal(100, rect.height) + rect.height = 200 + assert_equal(200, rect.height) + end + + def test_compatible + assert(!(CvRect.compatible? MyRect.new)) + MyRect.class_eval { def x; end } + assert(!(CvRect.compatible? MyRect.new)) + MyRect.class_eval { def y; end } + assert(!(CvRect.compatible? MyRect.new)) + MyRect.class_eval { def width; end } + assert(!(CvRect.compatible? MyRect.new)) + MyRect.class_eval { def height; end } + assert(CvRect.compatible? MyRect.new) + assert(CvRect.compatible? CvRect.new) + end + + def test_initialize + rect = CvRect.new + assert_equal(0, rect.x) + assert_equal(0, rect.y) + assert_equal(0, rect.width) + assert_equal(0, rect.height) + + rect = CvRect.new(10, 20, 30, 40) + assert_equal(10, rect.x) + assert_equal(20, rect.y) + assert_equal(30, rect.width) + assert_equal(40, rect.height) + + rect = CvRect.new(CvRect.new(10, 20, 30, 40)) + assert_equal(10, rect.x) + assert_equal(20, rect.y) + assert_equal(30, rect.width) + assert_equal(40, rect.height) + + assert_raise(TypeError) { + CvRect.new(DUMMY_OBJ) + } + assert_raise(ArgumentError) { + CvRect.new(1, 2) + } + assert_raise(ArgumentError) { + CvRect.new(1, 2, 3) + } + assert_raise(ArgumentError) { + CvRect.new(1, 2, 3, 4, 5) + } + end + + def test_center + center = CvRect.new(10, 20, 35, 45).center + assert_in_delta(27.5, center.x, 0.01) + assert_in_delta(42.5, center.y, 0.01) + end + + def test_points + points = CvRect.new(10, 20, 35, 45).points + assert_equal(4, points.size) + assert_in_delta(10, points[0].x, 0.01) + assert_in_delta(20, points[0].y, 0.01) + assert_in_delta(10, points[1].x, 0.01) + assert_in_delta(65, points[1].y, 0.01) + assert_in_delta(45, points[2].x, 0.01) + assert_in_delta(65, points[2].y, 0.01) + assert_in_delta(45, points[3].x, 0.01) + assert_in_delta(20, points[3].y, 0.01) + end + + def test_top_left + tl = CvRect.new(10, 20, 35, 45).top_left + assert_equal(10, tl.x) + assert_equal(20, tl.y) + end + + def test_top_right + tr = CvRect.new(10, 20, 35, 45).top_right + assert_equal(45, tr.x) + assert_equal(20, tr.y) + end + + def test_bottom_left + bl = CvRect.new(10, 20, 35, 45).bottom_left + assert_equal(10, bl.x) + assert_equal(65, bl.y) + end + + def test_bottom_right + br = CvRect.new(10, 20, 35, 45).bottom_right + assert_equal(45, br.x) + assert_equal(65, br.y) + end + + def test_max_rect + rect1 = CvRect.new(10, 20, 30, 40) + rect2 = CvRect.new(30, 40, 70, 80) + rect3 = CvRect.max_rect(rect1, rect2) + assert_equal(10, rect3.x) + assert_equal(20, rect3.y) + assert_equal(90, rect3.width) + assert_equal(100, rect3.height) + end +end + diff --git a/test/test_cvscalar.rb b/test/test_cvscalar.rb new file mode 100755 index 00000000..2d72f867 --- /dev/null +++ b/test/test_cvscalar.rb @@ -0,0 +1,113 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvScalar +class TestCvScalar < OpenCVTestCase + def test_initialize + s = CvScalar.new + assert_in_delta([0, 0, 0, 0], s, 0.01) + + s = CvScalar.new(1.1) + assert_in_delta([1.1, 0, 0, 0], s, 0.01) + + s = CvScalar.new(1.1, 2.2) + assert_in_delta([1.1, 2.2, 0, 0], s, 0.01) + + s = CvScalar.new(1.1, 2.2, 3.3) + assert_in_delta([1.1, 2.2, 3.3, 0], s, 0.01) + + s = CvScalar.new(1.1, 2.2, 3.3, 4.4) + assert_in_delta([1.1, 2.2, 3.3, 4.4], s, 0.01) + end + + def test_aref + assert_in_delta([0, 0, 0, 0], CvScalar.new, 0.01) + assert_in_delta([10, 20, 30, 40], CvScalar.new(10, 20, 30, 40), 0.01) + assert_in_delta([0.1, 0.2, 0.3, 0.4], CvScalar.new(0.1, 0.2, 0.3, 0.4), 0.01) + end + + def test_aset + s = CvScalar.new + [10, 20, 30, 40].each_with_index { |x, i| + s[i] = x + } + assert_in_delta([10, 20, 30, 40], s, 0.01) + + s = CvScalar.new + [0.1, 0.2, 0.3, 0.4].each_with_index { |x, i| + s[i] = x + } + assert_in_delta([0.1, 0.2, 0.3, 0.4], s, 0.01) + end + + def test_sub + s1 = CvScalar.new(10, 20, 30, 40) + s2 = CvScalar.new(2, 4, 6, 8) + [s1.sub(s2), s1 - s2].each { |s| + assert_in_delta([8, 16, 24, 32], s, 0.01) + } + + s3 = CvScalar.new(0.2, 0.4, 0.6, 0.8) + [s2.sub(s3), s2 - s3].each { |s| + assert_in_delta([1.8, 3.6, 5.4, 7.2], s, 0.01) + } + + mat = CvMat.new(5, 5) + mask = CvMat.new(5, 5, :cv8u, 1) + mat.height.times { |j| + mat.width.times { |i| + mat[i, j] = CvScalar.new(1.5) + mask[i, j] = (i < 2 and j < 3) ? 1 : 0 + } + } + mat = CvScalar.new(0.1).sub(mat, mask) + + [CvMat.new(5, 5, :cv16u, 1), CvMat.new(5, 5, :cv8u, 3)].each { |msk| + assert_raise(TypeError) { + CvScalar.new.sub(mat, msk) + } + } + end + + def test_to_s + assert_equal("", CvScalar.new(10, 20, 30, 40).to_s) + assert_equal("", CvScalar.new(0.1, 0.2, 0.3, 0.4).to_s) + end + + def test_to_ary + [[10, 20, 30, 40], [0.1, 0.2, 0.3, 0.4]].each { |a| + s = CvScalar.new(*a) + b = s.to_ary + c = s.to_a # Alias + [b, c].each { |x| + assert_equal(Array, x.class) + assert_in_delta(a, x, 0.01) + } + } + end + + def test_cvcolor + assert_cvscalar_equal(CvColor::Black, CvScalar.new(0x0, 0x0, 0x0, 0)) + assert_cvscalar_equal(CvColor::Silver, CvScalar.new(0x0c, 0x0c, 0x0c, 0)) + assert_cvscalar_equal(CvColor::Gray, CvScalar.new(0x80, 0x80, 0x80, 0)) + assert_cvscalar_equal(CvColor::White, CvScalar.new(0xff, 0xff, 0xff, 0)) + assert_cvscalar_equal(CvColor::Maroon, CvScalar.new(0x0, 0x0, 0x80, 0)) + assert_cvscalar_equal(CvColor::Red, CvScalar.new(0x0, 0x0, 0xff, 0)) + assert_cvscalar_equal(CvColor::Purple, CvScalar.new(0x80, 0x0, 0x80, 0)) + assert_cvscalar_equal(CvColor::Fuchsia, CvScalar.new(0xff, 0x0, 0xff, 0)) + assert_cvscalar_equal(CvColor::Green, CvScalar.new(0x0, 0x80, 0x0, 0)) + assert_cvscalar_equal(CvColor::Lime, CvScalar.new(0x0, 0xff, 0x0, 0)) + assert_cvscalar_equal(CvColor::Olive, CvScalar.new(0x0, 0x80, 0x80, 0)) + assert_cvscalar_equal(CvColor::Yellow, CvScalar.new(0x0, 0xff, 0xff, 0)) + assert_cvscalar_equal(CvColor::Navy, CvScalar.new(0x80, 0x0, 0x0, 0)) + assert_cvscalar_equal(CvColor::Blue, CvScalar.new(0xff, 0x0, 0x0, 0)) + assert_cvscalar_equal(CvColor::Teal, CvScalar.new(0x80, 0x80, 0x0, 0)) + assert_cvscalar_equal(CvColor::Aqua, CvScalar.new(0xff, 0xff, 0x0, 0)) + end +end + diff --git a/test/test_cvseq.rb b/test/test_cvseq.rb new file mode 100755 index 00000000..a12c1f78 --- /dev/null +++ b/test/test_cvseq.rb @@ -0,0 +1,311 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvSeq +class TestCvSeq < OpenCVTestCase + def test_initialize + types = [CV_SEQ_ELTYPE_POINT, CV_SEQ_ELTYPE_POINT3D, CV_SEQ_ELTYPE_CODE, CV_SEQ_ELTYPE_INDEX] + kinds = [CV_SEQ_KIND_GENERIC, CV_SEQ_KIND_CURVE, CV_SEQ_KIND_BIN_TREE, CV_SEQ_KIND_GRAPH, CV_SEQ_KIND_SUBDIV2D] + flags = [CV_SEQ_FLAG_CLOSED, CV_SEQ_FLAG_SIMPLE, CV_SEQ_FLAG_CONVEX, CV_SEQ_FLAG_HOLE] + types.each { |type| + kinds.each { |kind| + flags.each { |flag| + seq_flag = type | kind | flag + assert_equal(CvSeq, CvSeq.new(seq_flag).class) + } + } + } + + [CV_SEQ_POINT_SET, CV_SEQ_POINT3D_SET, CV_SEQ_POLYLINE, CV_SEQ_POLYGON, + CV_SEQ_CONTOUR, CV_SEQ_SIMPLE_POLYGON, CV_SEQ_CHAIN, CV_SEQ_CHAIN_CONTOUR, + CV_SEQ_INDEX ].each { |seq_flag| + assert_equal(CvSeq, CvSeq.new(seq_flag).class) + } + + # Unsupported types + [CV_SEQ_ELTYPE_PTR, CV_SEQ_ELTYPE_PPOINT].each { |type| + assert_raise(ArgumentError) { + CvSeq.new(type) + } + } + end + + def test_total + seq1 = CvSeq.new(CV_SEQ_ELTYPE_POINT) + assert_equal(0, seq1.total) + + seq1.push(CvPoint.new(1, 2)) + assert_equal(1, seq1.total) + + seq1.push(CvPoint.new(3, 4)) + assert_equal(2, seq1.total) + # Alias + assert_equal(2, seq1.length) + assert_equal(2, seq1.size) + end + + def test_empty + assert(CvSeq.new(CV_SEQ_ELTYPE_POINT).empty?) + end + + def test_aref + seq1 = CvSeq.new(CV_SEQ_ELTYPE_POINT) + seq1.push(CvPoint.new(10, 20), CvPoint.new(30, 40), CvPoint.new(50, 60)) + + assert_equal(CvPoint, seq1[0].class) + assert_equal(10, seq1[0].x) + assert_equal(20, seq1[0].y) + assert_equal(30, seq1[1].x) + assert_equal(40, seq1[1].y) + assert_equal(50, seq1[2].x) + assert_equal(60, seq1[2].y) + + seq2 = CvSeq.new(CV_SEQ_ELTYPE_INDEX) + seq2.push(10, 20, 30) + assert_kind_of(Integer, seq2[0]) + assert_equal(10, seq2[0]) + assert_equal(20, seq2[1]) + assert_equal(30, seq2[2]) + end + + def test_push + seq1 = CvSeq.new(CV_SEQ_ELTYPE_POINT).push(CvPoint.new(10, 20), CvPoint.new(30, 40)) + + assert_equal(2, seq1.total) + assert_equal(CvPoint, seq1[0].class) + assert_equal(10, seq1[0].x) + assert_equal(20, seq1[0].y) + assert_equal(CvPoint, seq1[1].class) + assert_equal(30, seq1[1].x) + assert_equal(40, seq1[1].y) + + seq2 = CvSeq.new(CV_SEQ_ELTYPE_POINT).push(CvPoint.new(50, 60)) + seq2.push(seq1) + assert_equal(3, seq2.total) + assert_equal(CvPoint, seq2[0].class) + assert_equal(50, seq2[0].x) + assert_equal(60, seq2[0].y) + assert_equal(CvPoint, seq2[1].class) + assert_equal(10, seq2[1].x) + assert_equal(20, seq2[1].y) + assert_equal(CvPoint, seq2[2].class) + assert_equal(30, seq2[2].x) + assert_equal(40, seq2[2].y) + + seq3 = CvSeq.new(CV_SEQ_ELTYPE_INDEX).push(10) + seq4 = CvSeq.new(CV_SEQ_ELTYPE_INDEX).push(20, 30) + seq3.push(seq4) + assert_equal(3, seq3.total) + assert_kind_of(Integer, seq3[0]) + assert_equal(10, seq3[0]) + assert_equal(20, seq3[1]) + assert_equal(30, seq3[2]) + + assert_raise(TypeError) { + seq1.push(55.5, 66.6) + } + + assert_raise(TypeError) { + seq3 = CvSeq.new(CV_SEQ_ELTYPE_INDEX).push(55, 66) + seq1.push(seq3) + } + end + + def test_pop + seq1 = CvSeq.new(CV_SEQ_ELTYPE_POINT).push(CvPoint.new(10, 20), CvPoint.new(30, 40)) + point1 = seq1.pop + assert_equal(CvPoint, point1.class) + assert_equal(30, point1.x) + assert_equal(40, point1.y) + + assert_equal(1, seq1.total) + assert_equal(CvPoint, seq1[0].class) + assert_equal(10, seq1[0].x) + assert_equal(20, seq1[0].y) + + assert_nil(CvSeq.new(CV_SEQ_ELTYPE_POINT).pop) + + seq2 = CvSeq.new(CV_SEQ_ELTYPE_INDEX).push(10, 20, 30) + assert_equal(30, seq2.pop) + assert_equal(20, seq2.pop) + assert_equal(10, seq2.pop) + end + + def test_clear + seq1 = CvSeq.new(CV_SEQ_ELTYPE_POINT).push(CvPoint.new(10, 20), CvPoint.new(30, 40)) + seq1.clear + assert_not_nil(seq1) + assert_equal(0, seq1.total) + end + + def test_unshift + seq1 = CvSeq.new(CV_SEQ_ELTYPE_POINT).unshift(CvPoint.new(10, 20), CvPoint.new(30, 40)) + + assert_equal(2, seq1.total) + assert_equal(CvPoint, seq1[0].class) + assert_equal(30, seq1[0].x) + assert_equal(40, seq1[0].y) + assert_equal(CvPoint, seq1[1].class) + assert_equal(10, seq1[1].x) + assert_equal(20, seq1[1].y) + + seq2 = CvSeq.new(CV_SEQ_ELTYPE_POINT).unshift(CvPoint.new(50, 60)) + seq2.unshift(seq1) + assert_equal(3, seq2.total) + assert_equal(CvPoint, seq1[0].class) + assert_equal(30, seq1[0].x) + assert_equal(40, seq1[0].y) + assert_equal(CvPoint, seq1[1].class) + assert_equal(10, seq1[1].x) + assert_equal(20, seq1[1].y) + assert_equal(CvPoint, seq2[2].class) + assert_equal(50, seq2[2].x) + assert_equal(60, seq2[2].y) + + seq3 = CvSeq.new(CV_SEQ_ELTYPE_INDEX).unshift(10, 20, 30) + assert_equal(3, seq3.total) + assert_equal(30, seq3[0]) + assert_equal(20, seq3[1]) + assert_equal(10, seq3[2]) + + assert_raise(TypeError) { + seq1.unshift(10) + } + + assert_raise(TypeError) { + seq3 = CvSeq.new(CV_SEQ_ELTYPE_INDEX).push(10, 20, 30) + seq1.unshift(seq3) + } + end + + def test_shift + seq1 = CvSeq.new(CV_SEQ_ELTYPE_POINT).push(CvPoint.new(10, 20), CvPoint.new(30, 40)) + point1 = seq1.shift + assert_equal(CvPoint, point1.class) + assert_equal(10, point1.x) + assert_equal(20, point1.y) + + assert_equal(1, seq1.total) + assert_equal(CvPoint, seq1[0].class) + assert_equal(30, seq1[0].x) + assert_equal(40, seq1[0].y) + + seq2 = CvSeq.new(CV_SEQ_ELTYPE_INDEX).push(10, 20, 30) + assert_equal(10, seq2.shift) + assert_equal(20, seq2.shift) + assert_equal(30, seq2.shift) + + assert_nil(CvSeq.new(CV_SEQ_ELTYPE_POINT).shift) + end + + def test_first + seq1 = CvSeq.new(CV_SEQ_ELTYPE_POINT).push(CvPoint.new(10, 20), CvPoint.new(30, 40), CvPoint.new(50, 60)) + point1 = seq1.first + assert_equal(CvPoint, point1.class) + assert_equal(10, point1.x) + assert_equal(20, point1.y) + + seq2 = CvSeq.new(CV_SEQ_ELTYPE_INDEX).push(10, 20, 30) + assert_equal(10, seq2.first) + end + + def test_last + seq1 = CvSeq.new(CV_SEQ_ELTYPE_POINT).push(CvPoint.new(10, 20), CvPoint.new(30, 40), CvPoint.new(50, 60)) + point1 = seq1.last + assert_equal(CvPoint, point1.class) + assert_equal(50, point1.x) + assert_equal(60, point1.y) + + seq2 = CvSeq.new(CV_SEQ_ELTYPE_INDEX).push(10, 20, 30) + assert_equal(30, seq2.last) + end + + def test_each + seq1 = CvSeq.new(CV_SEQ_ELTYPE_POINT).push(CvPoint.new(10, 20), CvPoint.new(30, 40), CvPoint.new(50, 60)) + i = 0 + seq1.each { |s| + assert_equal(CvPoint, s.class) + assert_equal(seq1[i].x, s.x) + assert_equal(seq1[i].y, s.y) + i += 1 + } + assert_equal(3, i) + + seq2 = CvSeq.new(CV_SEQ_ELTYPE_INDEX).push(10, 20, 30) + i = 0 + seq2.each { |s| + assert_equal(seq2[i], s) + i += 1 + } + assert_equal(3, i) + end + + def test_each_index + seq1 = CvSeq.new(CV_SEQ_ELTYPE_POINT).push(CvPoint.new(10, 20), CvPoint.new(30, 40), CvPoint.new(50, 60)) + n = 0 + seq1.each_index { |i| + assert_equal(n, i) + n += 1 + } + assert_equal(3, n) + end + + def test_insert + seq1 = CvSeq.new(CV_SEQ_ELTYPE_POINT).push(CvPoint.new(10, 20), CvPoint.new(30, 40)) + seq1.insert(1, CvPoint.new(50, 60)) + assert_equal(3, seq1.total) + assert_equal(CvPoint, seq1[0].class) + assert_equal(10, seq1[0].x) + assert_equal(20, seq1[0].y) + assert_equal(CvPoint, seq1[1].class) + assert_equal(50, seq1[1].x) + assert_equal(60, seq1[1].y) + assert_equal(CvPoint, seq1[2].class) + assert_equal(30, seq1[2].x) + assert_equal(40, seq1[2].y) + + seq2 = CvSeq.new(CV_SEQ_ELTYPE_INDEX).push(10, 20) + seq2.insert(1, 15) + assert_equal(3, seq2.total) + assert_equal(10, seq2[0]) + assert_equal(15, seq2[1]) + assert_equal(20, seq2[2]) + end + + def test_remove + seq1 = CvSeq.new(CV_SEQ_ELTYPE_POINT).push(CvPoint.new(10, 20), CvPoint.new(30, 40), CvPoint.new(50, 60)) + + seq1.remove(1) + assert_equal(2, seq1.total) + assert_equal(CvPoint, seq1[0].class) + assert_equal(10, seq1[0].x) + assert_equal(20, seq1[0].y) + assert_equal(CvPoint, seq1[1].class) + assert_equal(50, seq1[1].x) + assert_equal(60, seq1[1].y) + end + + # These methods are tested in TestCvMat_imageprocessing#test_find_contours + # (test_cvmat_imageprocessing.rb) + # def test_h_prev + # flunk('FIXME: CvSeq#h_prev is not tested yet.') + # end + + # def test_h_next + # flunk('FIXME: CvSeq#h_next is not tested yet.') + # end + + # def test_v_prev + # flunk('FIXME: CvSeq#v_prev is not tested yet.') + # end + + # def test_v_next + # flunk('FIXME: CvSeq#v_next is not tested yet.') + # end +end + diff --git a/test/test_cvsize.rb b/test/test_cvsize.rb new file mode 100755 index 00000000..d3be2668 --- /dev/null +++ b/test/test_cvsize.rb @@ -0,0 +1,75 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvSize +class TestCvSize < OpenCVTestCase + class MySize; end + + def test_width + size = CvSize.new + size.width = 100 + assert_equal(100, size.width) + size.width = 200 + assert_equal(200, size.width) + end + + def test_height + size = CvSize.new + size.height = 100 + assert_equal(100, size.height) + size.height = 200 + assert_equal(200, size.height) + end + + def test_compatible + assert(!(CvSize.compatible? MySize.new)) + MySize.class_eval { def width; end } + assert(!(CvSize.compatible? MySize.new)) + MySize.class_eval { def height; end } + assert(CvSize.compatible? MySize.new) + assert(CvSize.compatible? CvSize.new) + end + + def test_initialize + size = CvSize.new + assert_equal(0, size.width) + assert_equal(0, size.height) + + size = CvSize.new(10, 20) + assert_equal(10, size.width) + assert_equal(20, size.height) + + size = CvSize.new(CvSize.new(10, 20)) + assert_equal(10, size.width) + assert_equal(20, size.height) + + assert_raise(TypeError) { + CvSize.new(DUMMY_OBJ) + } + assert_raise(ArgumentError) { + CvSize.new(1, 2, 3) + } + end + + def test_to_s + size = CvSize.new(10, 20) + assert_equal('', size.to_s) + end + + def test_to_ary + a = CvSize.new(10, 20).to_ary + assert_equal(10, a[0]) + assert_equal(20, a[1]) + + # Alias + a = CvSize.new(10, 20).to_a + assert_equal(10, a[0]) + assert_equal(20, a[1]) + end +end + diff --git a/test/test_cvsize2d32f.rb b/test/test_cvsize2d32f.rb new file mode 100755 index 00000000..b0b38527 --- /dev/null +++ b/test/test_cvsize2d32f.rb @@ -0,0 +1,75 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvSize2D32f +class TestCvSize2D32f < OpenCVTestCase + class MySize; end + + def test_width + size = CvSize2D32f.new + size.width = 1.1 + assert_in_delta(1.1, size.width, 0.001) + size.width = 2.2 + assert_in_delta(2.2, size.width, 0.001) + end + + def test_height + size = CvSize2D32f.new + size.height = 1.1 + assert_in_delta(1.1, size.height, 0.001) + size.height = 2.2 + assert_in_delta(2.2, size.height, 0.001) + end + + def test_compatible + assert(!(CvSize2D32f.compatible? MySize.new)) + MySize.class_eval { def width; end } + assert(!(CvSize2D32f.compatible? MySize.new)) + MySize.class_eval { def height; end } + assert(CvSize2D32f.compatible? MySize.new) + assert(CvSize2D32f.compatible? CvSize2D32f.new) + end + + def test_initialize + size = CvSize2D32f.new + assert_in_delta(0, size.width, 0.001) + assert_in_delta(0, size.height, 0.001) + + size = CvSize2D32f.new(1.1, 2.2) + assert_in_delta(1.1, size.width, 0.001) + assert_in_delta(2.2, size.height, 0.001) + + size = CvSize2D32f.new(CvSize2D32f.new(1.1, 2.2)) + assert_in_delta(1.1, size.width, 0.001) + assert_in_delta(2.2, size.height, 0.001) + + assert_raise(TypeError) { + CvSize2D32f.new(DUMMY_OBJ) + } + assert_raise(ArgumentError) { + CvSize2D32f.new(1, 2, 3) + } + end + + def test_to_s + size = CvSize2D32f.new(1.1, 2.2) + assert_equal('', size.to_s) + end + + def test_to_ary + a = CvSize2D32f.new(1.1, 2.2).to_ary + assert_in_delta(1.1, a[0], 0.001) + assert_in_delta(2.2, a[1], 0.001) + + # Alias + a = CvSize2D32f.new(1.1, 2.2).to_a + assert_in_delta(1.1, a[0], 0.001) + assert_in_delta(2.2, a[1], 0.001) + end +end + diff --git a/test/test_cvslice.rb b/test/test_cvslice.rb new file mode 100755 index 00000000..14297564 --- /dev/null +++ b/test/test_cvslice.rb @@ -0,0 +1,31 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvSlice +class TestCvSlice < OpenCVTestCase + def setup + @slice = CvSlice.new(2, 4) + end + + def test_initialize + assert_equal(CvSlice, @slice.class) + end + + def test_start_index + assert_equal(2, @slice.start_index) + @slice.start_index = 3 + assert_equal(3, @slice.start_index) + end + + def test_end_index + assert_equal(4, @slice.end_index) + @slice.end_index = 5 + assert_equal(5, @slice.end_index) + end +end + diff --git a/test/test_cvsurfparams.rb b/test/test_cvsurfparams.rb new file mode 100755 index 00000000..945b28d8 --- /dev/null +++ b/test/test_cvsurfparams.rb @@ -0,0 +1,57 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvSURFParams +class TestCvSURFParams < OpenCVTestCase + def setup + @surf_param1 = CvSURFParams.new(345.6) + end + + def test_initialize + sp1 = CvSURFParams.new(345.6) + assert_equal(false, sp1.extended) + assert_in_delta(345.6, sp1.hessian_threshold, 0.001) + assert_equal(3, sp1.n_octaves) + assert_equal(4, sp1.n_octave_layers) + + sp2 = CvSURFParams.new(456.7, true, 4, 5) + assert_equal(true, sp2.extended) + assert_in_delta(456.7, sp2.hessian_threshold, 0.001) + assert_equal(4, sp2.n_octaves) + assert_equal(5, sp2.n_octave_layers) + end + + def test_extended + assert_equal(false, @surf_param1.extended) + + @surf_param1.extended = true + assert_equal(true, @surf_param1.extended) + end + + def test_hessian_threshold + assert_in_delta(345.6, @surf_param1.hessian_threshold, 0.001) + + @surf_param1.hessian_threshold = 456.7 + assert_in_delta(456.7, @surf_param1.hessian_threshold, 0.001) + end + + def test_n_octaves + assert_equal(3, @surf_param1.n_octaves) + + @surf_param1.n_octaves = 4 + assert_equal(4, @surf_param1.n_octaves) + end + + def test_n_octave_layers + assert_equal(4, @surf_param1.n_octave_layers) + + @surf_param1.n_octave_layers = 5 + assert_equal(5, @surf_param1.n_octave_layers) + end +end + diff --git a/test/test_cvsurfpoint.rb b/test/test_cvsurfpoint.rb new file mode 100755 index 00000000..c1fb6c76 --- /dev/null +++ b/test/test_cvsurfpoint.rb @@ -0,0 +1,66 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvSURFPoint +class TestCvSURFPoint < OpenCVTestCase + def setup + @surf_point1 = CvSURFPoint.new(CvPoint2D32f.new(0, 0), 0, 0, 0, 0) + end + + def test_initialize + sp1 = CvSURFPoint.new(CvPoint2D32f.new(1.1, 2.2), 1, 10, 12.3, 45.6) + assert_in_delta(1.1, sp1.pt.x, 0.001) + assert_in_delta(2.2, sp1.pt.y, 0.001) + assert_equal(1, sp1.laplacian) + assert_equal(10, sp1.size) + assert_in_delta(12.3, sp1.dir, 0.001) + assert_in_delta(45.6, sp1.hessian, 0.001) + end + + def test_pt + assert_in_delta(0, @surf_point1.pt.x, 0.001) + assert_in_delta(0, @surf_point1.pt.y, 0.001) + + @surf_point1.pt = CvPoint2D32f.new(12.3, 45.6) + assert_in_delta(12.3, @surf_point1.pt.x, 0.001) + assert_in_delta(45.6, @surf_point1.pt.y, 0.001) + + assert_raise(TypeError) { + @surf_point1.pt = DUMMY_OBJ + } + end + + def test_laplacian + assert_equal(0, @surf_point1.laplacian) + + @surf_point1.laplacian = -1 + assert_equal(-1, @surf_point1.laplacian) + end + + def test_size + assert_equal(0, @surf_point1.size) + + @surf_point1.size = 10 + assert_equal(10, @surf_point1.size) + end + + def test_dir + assert_in_delta(0, @surf_point1.dir, 0.001) + + @surf_point1.dir = 23.4 + assert_in_delta(23.4, @surf_point1.dir, 0.001) + end + + def test_hessian + assert_in_delta(0, @surf_point1.hessian, 0.001) + + @surf_point1.hessian = 2.1 + assert_in_delta(2.1, @surf_point1.hessian, 0.001) + end +end + diff --git a/test/test_cvtermcriteria.rb b/test/test_cvtermcriteria.rb new file mode 100755 index 00000000..b8cb1e30 --- /dev/null +++ b/test/test_cvtermcriteria.rb @@ -0,0 +1,56 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvTermCriteria +class TestCvTermCriteria < OpenCVTestCase + def setup + @criteria1 = CvTermCriteria.new + @criteria2 = CvTermCriteria.new(100) + @criteria3 = CvTermCriteria.new(nil, 0.01) + @criteria4 = CvTermCriteria.new(100, 0.01) + end + + def test_initialize + assert_not_nil(@criteria1) + assert_equal(CvTermCriteria, @criteria1.class) + assert_not_nil(@criteria2) + assert_equal(CvTermCriteria, @criteria2.class) + assert_not_nil(@criteria3) + assert_equal(CvTermCriteria, @criteria3.class) + assert_not_nil(@criteria4) + assert_equal(CvTermCriteria, @criteria4.class) + end + + def test_type + assert_equal(0, @criteria1.type) + assert_equal(CV_TERMCRIT_ITER, @criteria2.type) + assert_equal(CV_TERMCRIT_EPS, @criteria3.type) + assert_equal(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, @criteria4.type) + end + + def test_max + assert_nil(@criteria1.max) + assert_equal(100, @criteria2.max) + assert_nil(@criteria3.max) + assert_equal(100, @criteria4.max) + + @criteria1.max = 999 + assert_equal(999, @criteria1.max) + end + + def test_eps + assert_nil(@criteria1.eps) + assert_nil(@criteria2.eps) + assert_in_delta(0.01, @criteria3.eps, 0.001) + assert_in_delta(0.01, @criteria4.eps, 0.001) + + @criteria1.eps = 3.14 + assert_in_delta(3.14, @criteria1.eps, 0.001) + end +end + diff --git a/test/test_cvtwopoints.rb b/test/test_cvtwopoints.rb new file mode 100755 index 00000000..654b402c --- /dev/null +++ b/test/test_cvtwopoints.rb @@ -0,0 +1,40 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvTwoPoints +class TestCvTwoPoints < OpenCVTestCase + def setup + @twopoints = CvTwoPoints.new + end + + def test_initialize + assert_not_nil(@twopoints) + assert_equal(CvTwoPoints, @twopoints.class) + end + + def test_point + assert_not_nil(@twopoints.point1) + assert_not_nil(@twopoints.point2) + assert_equal(CvPoint, @twopoints.point1.class) + assert_equal(CvPoint, @twopoints.point2.class) + end + + def test_aref + assert_not_nil(@twopoints[0]) + assert_not_nil(@twopoints[1]) + assert_equal(CvPoint, @twopoints[0].class) + assert_equal(CvPoint, @twopoints[1].class) + end + + def test_to_ary + assert_equal(Array, @twopoints.to_ary.class) + assert_equal(2, @twopoints.to_ary.size) + assert_equal(2, @twopoints.to_a.size) + end +end + diff --git a/test/test_cvvideowriter.rb b/test/test_cvvideowriter.rb new file mode 100755 index 00000000..c79fbcc6 --- /dev/null +++ b/test/test_cvvideowriter.rb @@ -0,0 +1,58 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::CvVideoWriter +class TestCvVideoWriter < OpenCVTestCase + OUTPUT_FILENAME = 'videowriter_result.avi' + + def test_initialize + vw = CvVideoWriter.new(OUTPUT_FILENAME, 'MJPG', 15, CvSize.new(320, 240)) + assert_equal(CvVideoWriter, vw.class) + vw.close + + vw = CvVideoWriter.new(OUTPUT_FILENAME, 'MJPG', 15, CvSize.new(320, 240), false) + assert_equal(CvVideoWriter, vw.class) + vw.close + + ## Supported only Windows(?) + # vw = CvVideoWriter.new(OUTPUT_FILENAME, nil, 15, CvSize.new(320, 240), false) + # assert_equal(CvVideoWriter, vw.class) + # vw.close + + CvVideoWriter.new(OUTPUT_FILENAME, 'MJPG', 15, CvSize.new(320, 240)) { |vw| + assert_equal(CvVideoWriter, vw.class) + } + + assert_raise(TypeError) { + vw = CvVideoWriter.new(123, 'MJPG', 15, CvSize.new(320, 240), false) + } + end + + def test_write + img = IplImage.load(FILENAME_LENA256x256) + vw = CvVideoWriter.new(OUTPUT_FILENAME, 'MJPG', 15, CvSize.new(256, 256)) + vw.write img + vw.close + + CvVideoWriter.new(OUTPUT_FILENAME, 'MJPG', 15, CvSize.new(256, 256)) { |vw| + vw.write img + } + + assert_raise(TypeError) { + CvVideoWriter.new(OUTPUT_FILENAME, 'MJPG', 15, CvSize.new(256, 256)) { |vw| + vw.write DUMMY_OBJ + } + } + end + + def test_close + vw = CvVideoWriter.new(OUTPUT_FILENAME, 'MJPG', 15, CvSize.new(320, 240)) + vw.close + end +end + diff --git a/test/test_eigenfaces.rb b/test/test_eigenfaces.rb new file mode 100755 index 00000000..3552cc2d --- /dev/null +++ b/test/test_eigenfaces.rb @@ -0,0 +1,93 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8-unix -*- +require 'test/unit' +require 'opencv' +require 'date' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::EigenFaces +class TestEigenFaces < OpenCVTestCase + def setup + @eigenfaces = EigenFaces.new + + @eigenfaces_trained = EigenFaces.new + @images = [CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_GRAYSCALE)] * 2 + @labels = [1, 2] + @eigenfaces_trained.train(@images, @labels) + end + + def test_initialize + [EigenFaces.new, EigenFaces.new(1), EigenFaces.new(1, 99999)].each { |ef| + assert_equal(EigenFaces, ef.class) + } + + assert_raise(TypeError) { + EigenFaces.new(DUMMY_OBJ) + } + + assert_raise(TypeError) { + EigenFaces.new(1, DUMMY_OBJ) + } + end + + def test_train + assert_nil(@eigenfaces.train(@images, @labels)) + + assert_raise(TypeError) { + @eigenfaces.train(DUMMY_OBJ, @labels) + } + + assert_raise(TypeError) { + @eigenfaces.train(@images, DUMMY_OBJ) + } + end + + def test_predict + predicted_label, predicted_confidence = @eigenfaces_trained.predict(@images[0]) + assert_equal(@labels[0], predicted_label) + assert_in_delta(0.0, predicted_confidence, 0.01) + + assert_raise(TypeError) { + @eigenfaces_trained.predict(DUMMY_OBJ) + } + end + + def test_save + filename = "eigenfaces_save-#{DateTime.now.strftime('%Y%m%d%H%M%S')}.xml" + begin + @eigenfaces_trained.save(filename) + assert(File.exist? filename) + ensure + File.delete filename + end + assert_raise(TypeError) { + @eigenfaces_trained.save(DUMMY_OBJ) + } + end + + def test_load + assert_nothing_raised { + @eigenfaces_trained.load('eigenfaces_save.xml') + } + assert_raise(TypeError) { + @eigenfaces_trained.load(DUMMY_OBJ) + } + end + + def test_name + assert_equal('FaceRecognizer.Eigenfaces', @eigenfaces.name) + end + + def test_get_mat + mat = @eigenfaces_trained.get_mat('eigenvalues') + assert_not_nil(mat) + assert_equal(CvMat, mat.class) + + assert_raise(TypeError) { + @eigenfaces_trained.get_mat(DUMMY_OBJ) + } + end +end + diff --git a/test/test_fisherfaces.rb b/test/test_fisherfaces.rb new file mode 100755 index 00000000..298bfdd1 --- /dev/null +++ b/test/test_fisherfaces.rb @@ -0,0 +1,93 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8-unix -*- +require 'test/unit' +require 'opencv' +require 'date' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::FisherFaces +class TestFisherFaces < OpenCVTestCase + def setup + @fisherfaces = FisherFaces.new + + @fisherfaces_trained = FisherFaces.new + @images = [CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_GRAYSCALE)] * 2 + @labels = [1, 2] + @fisherfaces_trained.train(@images, @labels) + end + + def test_initialize + [FisherFaces.new, FisherFaces.new(1), FisherFaces.new(1, 99999)].each { |ff| + assert_equal(FisherFaces, ff.class) + } + + assert_raise(TypeError) { + FisherFaces.new(DUMMY_OBJ) + } + + assert_raise(TypeError) { + FisherFaces.new(1, DUMMY_OBJ) + } + end + + def test_train + assert_nil(@fisherfaces.train(@images, @labels)) + + assert_raise(TypeError) { + @fisherfaces.train(DUMMY_OBJ, @labels) + } + + assert_raise(TypeError) { + @fisherfaces.train(@images, DUMMY_OBJ) + } + end + + def test_predict + predicted_label, predicted_confidence = @fisherfaces_trained.predict(@images[0]) + assert_equal(@labels[0], predicted_label) + assert_in_delta(0.0, predicted_confidence, 0.01) + + assert_raise(TypeError) { + @fisherfaces_trained.predict(DUMMY_OBJ) + } + end + + def test_save + filename = "fisherfaces_save-#{DateTime.now.strftime('%Y%m%d%H%M%S')}.xml" + begin + @fisherfaces_trained.save(filename) + assert(File.exist? filename) + ensure + File.delete filename + end + assert_raise(TypeError) { + @fisherfaces_trained.save(DUMMY_OBJ) + } + end + + def test_load + assert_nothing_raised { + @fisherfaces.load('fisherfaces_save.xml') + } + assert_raise(TypeError) { + @fisherfaces.load(DUMMY_OBJ) + } + end + + def test_name + assert_equal('FaceRecognizer.Fisherfaces', @fisherfaces.name) + end + + def test_get_mat + mat = @fisherfaces_trained.get_mat('eigenvalues') + assert_not_nil(mat) + assert_equal(CvMat, mat.class) + + assert_raise(TypeError) { + @fisherfaces_trained.get_mat(DUMMY_OBJ) + } + end +end + diff --git a/test/test_iplconvkernel.rb b/test/test_iplconvkernel.rb new file mode 100755 index 00000000..2e97c712 --- /dev/null +++ b/test/test_iplconvkernel.rb @@ -0,0 +1,54 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::IplConvKernel +class TestIplConvKernel < OpenCVTestCase + def test_initialize + [:rect, :cross, :ellipse, CV_SHAPE_RECT, CV_SHAPE_CROSS, CV_SHAPE_ELLIPSE].each { |shape| + kernel = IplConvKernel.new(5, 5, 2, 2, shape) + assert_not_nil(kernel) + } + + values = [1] * 25 + [:custom, CV_SHAPE_CUSTOM].each { |shape| + kernel = IplConvKernel.new(5, 5, 2, 2, shape, values) + assert_not_nil(kernel) + } + + [:custom, CV_SHAPE_CUSTOM].each { |shape| + assert_raise(ArgumentError) { + IplConvKernel.new(5, 5, 2, 2, shape) + } + } + + assert_raise(TypeError) { + IplConvKernel.new(5, 5, 2, 2, :foobar) + } + end + + def test_size + kernel = IplConvKernel.new(5, 4, 2, 2, :rect) + size = kernel.size + assert_equal(5, size.width) + assert_equal(4, size.height) + + assert_equal(5, kernel.cols) + assert_equal(4, kernel.rows) + end + + def test_anchor + kernel = IplConvKernel.new(5, 4, 3, 2, :rect) + a = kernel.anchor + assert_equal(3, a.x) + assert_equal(2, a.y) + + assert_equal(3, kernel.anchor_x) + assert_equal(2, kernel.anchor_y) + end +end + diff --git a/test/test_iplimage.rb b/test/test_iplimage.rb new file mode 100755 index 00000000..c1f9f664 --- /dev/null +++ b/test/test_iplimage.rb @@ -0,0 +1,232 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::IplImage +class TestIplImage < OpenCVTestCase + def should_classify_images_as(filename, classification) + assert_equal(OpenCV::IplImage::load(filename, OpenCV::CV_LOAD_IMAGE_GRAYSCALE).smoothness[0], classification) + end + + def test_initialize + img = IplImage.new(10, 20) + assert_equal(10, img.width) + assert_equal(20, img.height) + assert_equal(:cv8u, img.depth) + assert_equal(3, img.channel) + + img = IplImage.new(30, 40, :cv32f, 1) + assert_equal(30, img.width) + assert_equal(40, img.height) + assert_equal(:cv32f, img.depth) + assert_equal(1, img.channel) + end + + def test_load + img1 = IplImage.load(FILENAME_CAT) + assert_equal(IplImage, img1.class) + assert_equal(375, img1.width) + assert_equal(500, img1.height) + assert_equal(:cv8u, img1.depth) + assert_equal(3, img1.channel) + + img2 = IplImage.load(FILENAME_CAT, CV_LOAD_IMAGE_GRAYSCALE) + assert_equal(IplImage, img2.class) + assert_equal(375, img2.width) + assert_equal(500, img2.height) + assert_equal(:cv8u, img2.depth) + assert_equal(1, img2.channel) + + img3 = IplImage.load(FILENAME_CAT, CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR) + assert_equal(IplImage, img3.class) + assert_equal(375, img3.width) + assert_equal(500, img3.height) + assert_equal(:cv8u, img3.depth) + assert_equal(3, img3.channel) + + assert_raise(ArgumentError) { + IplImage.load + } + assert_raise(TypeError) { + IplImage.load(123) + } + assert_raise(TypeError) { + IplImage.load(FILENAME_CAT, 'foobar') + } + assert_raise(StandardError) { + IplImage.load('file/does/not/exist') + } + + # Uncomment the following lines to show the results + # snap img1, img2, img3 + end + + def test_decode + data = nil + open(FILENAME_CAT, 'rb') { |f| + data = f.read + } + data_ary = data.unpack("c*") + data_mat = CvMat.new(1, data_ary.size).set_data(data_ary) + expected = IplImage.load(FILENAME_CAT) + + img1 = IplImage.decode(data) + img2 = IplImage.decode(data_ary) + img3 = IplImage.decode(data_mat) + img4 = IplImage.decode(data, CV_LOAD_IMAGE_COLOR) + img5 = IplImage.decode(data_ary, CV_LOAD_IMAGE_COLOR) + img6 = IplImage.decode(data_mat, CV_LOAD_IMAGE_COLOR) + + [img1, img2, img3, img4, img5, img6].each { |img| + assert_equal(IplImage, img.class) + assert_equal(expected.rows, img.rows) + assert_equal(expected.cols, img.cols) + assert_equal(expected.channel, img.channel) + } + + expected_c1 = IplImage.load(FILENAME_CAT, CV_LOAD_IMAGE_GRAYSCALE) + img1c1 = IplImage.decode(data, CV_LOAD_IMAGE_GRAYSCALE) + img2c1 = IplImage.decode(data_ary, CV_LOAD_IMAGE_GRAYSCALE) + img3c1 = IplImage.decode(data_mat, CV_LOAD_IMAGE_GRAYSCALE) + + [img1c1, img2c1, img3c1].each { |img| + assert_equal(IplImage, img.class) + assert_equal(expected_c1.rows, img.rows) + assert_equal(expected_c1.cols, img.cols) + assert_equal(expected_c1.channel, img.channel) + } + + assert_raise(TypeError) { + IplImage.decode(DUMMY_OBJ) + } + assert_raise(TypeError) { + IplImage.decode(data, DUMMY_OBJ) + } + + # Uncomment the following line to show the result images + # snap img1, img2, img3 + end + + def test_roi + img = IplImage.new(20, 30) + rect = img.roi + assert_equal(0, rect.x) + assert_equal(0, rect.y) + assert_equal(img.width, rect.width) + assert_equal(img.height, rect.height) + + img.set_roi(CvRect.new(2, 3, 10, 20)) + rect = img.roi + assert_equal(2, rect.x) + assert_equal(3, rect.y) + assert_equal(10, rect.width) + assert_equal(20, rect.height) + + img.reset_roi + rect = img.roi + assert_equal(0, rect.x) + assert_equal(0, rect.y) + assert_equal(img.width, rect.width) + assert_equal(img.height, rect.height) + + img.set_roi(CvRect.new(1, 2, 5, 6)) {|image| + rect = image.roi + assert_equal(1, rect.x) + assert_equal(2, rect.y) + assert_equal(5, rect.width) + assert_equal(6, rect.height) + } + rect = img.roi + assert_equal(0, rect.x) + assert_equal(0, rect.y) + assert_equal(img.width, rect.width) + assert_equal(img.height, rect.height) + + # Alias + img.roi = CvRect.new(4, 5, 11, 12) + rect = img.roi + assert_equal(4, rect.x) + assert_equal(5, rect.y) + assert_equal(11, rect.width) + assert_equal(12, rect.height) + end + + def test_coi + img = IplImage.new(20, 30) + assert_equal(0, img.coi) + + img.set_coi(1) + assert_equal(1, img.coi) + + img.reset_coi + assert_equal(0, img.coi) + + img.set_coi(2) {|image| + assert_equal(2, image.coi) + } + assert_equal(0, img.coi) + + # Alias + img.coi = 1 + assert_equal(1, img.coi) + end + + def test_smoothness + asset_path = File.join(File.dirname(__FILE__), 'samples') + + for image in Array.new(7) { |e| e = File.join(asset_path, "smooth%d.jpg") % e } do + should_classify_images_as image, :smooth + end + + for image in Array.new(2) { |e| e = File.join(asset_path, "messy%d.jpg") % e } do + should_classify_images_as image, :messy + end + + for image in Array.new(10) { |e| e = File.join(asset_path, "blank%d.jpg") % e } do + should_classify_images_as image, :blank + end + + for image in Array.new(2) { |e| e = File.join(asset_path, "partially_blank%d.jpg") % e } do + should_classify_images_as image, :blank + end + end + + def test_pyr_segmentation + img0 = IplImage.load(FILENAME_CAT, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) + img0.set_roi(CvRect.new(0, 0, 256, 512)) + img1, seq1 = img0.pyr_segmentation(2, 255, 50) + assert_equal('963b26f51b14f175fbbf128e9b9e979f', hash_img(img1)) + assert_equal(11, seq1.total) + + assert_raise(CvStsAssert) { + img0.pyr_segmentation(-1, 255, 50) + } + assert_raise(CvStsAssert) { + img0.pyr_segmentation(1000, 255, 50) + } + assert_raise(CvStsAssert) { + img0.pyr_segmentation(4, -1, 50) + } + assert_raise(CvStsAssert) { + img0.pyr_segmentation(4, 255, -1) + } + assert_raise(TypeError) { + img0.pyr_segmentation(DUMMY_OBJ, 255, 50) + } + assert_raise(TypeError) { + img0.pyr_segmentation(4, DUMMY_OBJ, 50) + } + assert_raise(TypeError) { + img0.pyr_segmentation(4, 255, DUMMY_OBJ) + } + assert_raise(CvBadDepth) { + IplImage.new(10, 10, :cv32f, 2).pyr_segmentation(4, 255, 50) + } + end +end + + diff --git a/test/test_lbph.rb b/test/test_lbph.rb new file mode 100755 index 00000000..f2b53dbf --- /dev/null +++ b/test/test_lbph.rb @@ -0,0 +1,166 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8-unix -*- +require 'test/unit' +require 'opencv' +require 'date' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::LBPH +class TestLBPH < OpenCVTestCase + def setup + @lbph = LBPH.new + + @lbph_trained = LBPH.new + @lbph_update = LBPH.new + @images = [CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_GRAYSCALE)] * 2 + @labels = [1, 2] + @lbph_trained.train(@images, @labels) + end + + def test_initialize + [LBPH.new, LBPH.new(1), LBPH.new(1, 2, 3, 4, 5.0)].each { |lbph| + assert_equal(LBPH, lbph.class) + } + + assert_raise(TypeError) { + LBPH.new(DUMMY_OBJ) + } + assert_raise(TypeError) { + LBPH.new(1, DUMMY_OBJ) + } + assert_raise(TypeError) { + LBPH.new(1, 2, DUMMY_OBJ) + } + assert_raise(TypeError) { + LBPH.new(1, 2, 3, DUMMY_OBJ) + } + assert_raise(TypeError) { + LBPH.new(1, 2, 3, 4, DUMMY_OBJ) + } + end + + def test_train + assert_nil(@lbph.train(@images, @labels)) + + assert_raise(TypeError) { + @lbph.train(DUMMY_OBJ, @labels) + } + + assert_raise(TypeError) { + @lbph.train(@images, DUMMY_OBJ) + } + end + + def test_update + assert_nil(@lbph_update.train([@images[0]], [@labels[0]])) + assert_nil(@lbph_update.update([@images[1]], [@labels[1]])) + + assert_raise(TypeError) { + @lbph_update.update(DUMMY_OBJ, @labels) + } + + assert_raise(TypeError) { + @lbph_update.update(@images, DUMMY_OBJ) + } + end + + def test_predict + predicted_label, predicted_confidence = @lbph_trained.predict(@images[0]) + assert_equal(@labels[0], predicted_label) + assert_in_delta(0.0, predicted_confidence, 0.01) + + assert_raise(TypeError) { + @lbph_trained.predict(DUMMY_OBJ) + } + end + + def test_save + filename = "lbph_save-#{DateTime.now.strftime('%Y%m%d%H%M%S')}.xml" + begin + @lbph_trained.save(filename) + assert(File.exist? filename) + ensure + File.delete filename + end + assert_raise(TypeError) { + @lbph_trained.save(DUMMY_OBJ) + } + end + + def test_load + assert_nothing_raised { + @lbph.load('lbph_save.xml') + } + assert_raise(TypeError) { + @lbph.load(DUMMY_OBJ) + } + end + + def test_name + assert_equal('FaceRecognizer.LBPH', @lbph.name) + end + + def test_get_int + assert_equal(1, @lbph.get_int('radius')) + assert_equal(8, @lbph.get_int('neighbors')) + assert_equal(8, @lbph.get_int('grid_x')) + assert_equal(8, @lbph.get_int('grid_y')) + + assert_raise(TypeError) { + @lbph.get_int(DUMMY_OBJ) + } + end + + def test_get_double + assert_equal(Float::MAX, @lbph.get_double('threshold')) + + assert_raise(TypeError) { + @lbph.get_double(DUMMY_OBJ) + } + end + + def test_get_matvector + histgrams = @lbph_trained.get_matvector('histograms') + assert_equal(Array, histgrams.class) + assert_equal(2, histgrams.size) + assert_equal(CvMat, histgrams[0].class) + + assert_raise(TypeError) { + @lbph.get_matvector(DUMMY_OBJ) + } + end + + def test_set_int + @lbph.set_int('radius', 2) + @lbph.set_int('neighbors', 3) + @lbph.set_int('grid_x', 4) + @lbph.set_int('grid_y', 5) + + assert_equal(2, @lbph.get_int('radius')) + assert_equal(3, @lbph.get_int('neighbors')) + assert_equal(4, @lbph.get_int('grid_x')) + assert_equal(5, @lbph.get_int('grid_y')) + + assert_raise(TypeError) { + @lbph.set_int(DUMMY_OBJ, 1) + } + assert_raise(TypeError) { + @lbph.set_int('radius', DUMMY_OBJ) + } + end + + def test_set_double + @lbph.set_double('threshold', 1.0) + assert_in_delta(1.0, @lbph.get_double('threshold'), 0.001) + + assert_raise(TypeError) { + @lbph.set_double(DUMMY_OBJ, 1.0) + } + assert_raise(TypeError) { + @lbph.set_double('threshold', DUMMY_OBJ) + } + end +end + diff --git a/test/test_mouseevent.rb b/test/test_mouseevent.rb new file mode 100755 index 00000000..a8818380 --- /dev/null +++ b/test/test_mouseevent.rb @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV +include GUI + +# Tests for OpenCV::MouseEvent +class TestMouseEvent < OpenCVTestCase + def test_initialize + assert_not_nil(MouseEvent.new) + assert_equal(MouseEvent, MouseEvent.new.class) + end +end + diff --git a/test/test_opencv.rb b/test/test_opencv.rb index 4c57e7f7..0593628d 100755 --- a/test/test_opencv.rb +++ b/test/test_opencv.rb @@ -1,6 +1,360 @@ #!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' -$:.unshift(File.dirname(__FILE__) + '/../lib') +include OpenCV + +class TestOpenCV < OpenCVTestCase + def test_constants + # OpenCV version + assert_equal('2.4.12', CV_VERSION) + assert_equal(2, CV_MAJOR_VERSION) + assert_equal(4, CV_MINOR_VERSION) + assert_equal(12, CV_SUBMINOR_VERSION) + + assert_equal(2, CV_VERSION_EPOCH) + assert_equal(4, CV_VERSION_MAJOR) + assert_equal(12, CV_VERSION_MINOR) + assert_equal(0, CV_VERSION_REVISION) + + # Depths + assert_equal(0, CV_8U) + assert_equal(1, CV_8S) + assert_equal(2, CV_16U) + assert_equal(3, CV_16S) + assert_equal(4, CV_32S) + assert_equal(5, CV_32F) + assert_equal(6, CV_64F) + + assert_equal(0, CV_8UC1) + assert_equal(8, CV_8UC2) + assert_equal(16, CV_8UC3) + assert_equal(24, CV_8UC4) + assert_equal(1, CV_8SC1) + assert_equal(9, CV_8SC2) + assert_equal(17, CV_8SC3) + assert_equal(25, CV_8SC4) + assert_equal(2, CV_16UC1) + assert_equal(10, CV_16UC2) + assert_equal(18, CV_16UC3) + assert_equal(26, CV_16UC4) + assert_equal(3, CV_16SC1) + assert_equal(11, CV_16SC2) + assert_equal(19, CV_16SC3) + assert_equal(27, CV_16SC4) + assert_equal(4, CV_32SC1) + assert_equal(12, CV_32SC2) + assert_equal(20, CV_32SC3) + assert_equal(28, CV_32SC4) + assert_equal(5, CV_32FC1) + assert_equal(13, CV_32FC2) + assert_equal(21, CV_32FC3) + assert_equal(29, CV_32FC4) + assert_equal(6, CV_64FC1) + assert_equal(14, CV_64FC2) + assert_equal(22, CV_64FC3) + assert_equal(30, CV_64FC4) + + # Load image flags + assert_equal(-1, CV_LOAD_IMAGE_UNCHANGED) + assert_equal(0, CV_LOAD_IMAGE_GRAYSCALE) + assert_equal(1, CV_LOAD_IMAGE_COLOR) + assert_equal(2, CV_LOAD_IMAGE_ANYDEPTH) + assert_equal(4, CV_LOAD_IMAGE_ANYCOLOR) + + # Structuring element shapes + assert_equal(0, CV_SHAPE_RECT) + assert_equal(1, CV_SHAPE_CROSS) + assert_equal(2, CV_SHAPE_ELLIPSE) + assert_equal(100, CV_SHAPE_CUSTOM) + + # Types of morphological operations + assert_equal(2, CV_MOP_OPEN) + assert_equal(3, CV_MOP_CLOSE) + assert_equal(4, CV_MOP_GRADIENT) + assert_equal(5, CV_MOP_TOPHAT) + assert_equal(6, CV_MOP_BLACKHAT) + + # Types of the smoothing + assert_equal(0, CV_BLUR_NO_SCALE) + assert_equal(1, CV_BLUR) + assert_equal(2, CV_GAUSSIAN) + assert_equal(3, CV_MEDIAN) + assert_equal(4, CV_BILATERAL) + + # Border types + assert_equal(0, IPL_BORDER_CONSTANT) + assert_equal(1, IPL_BORDER_REPLICATE) + + # Thresholding types + assert_equal(0, CV_THRESH_BINARY) + assert_equal(1, CV_THRESH_BINARY_INV) + assert_equal(2, CV_THRESH_TRUNC) + assert_equal(3, CV_THRESH_TOZERO) + assert_equal(4, CV_THRESH_TOZERO_INV) + assert_equal(8, CV_THRESH_OTSU) + + # Adaptive methods + assert_equal(0, CV_ADAPTIVE_THRESH_MEAN_C) + assert_equal(1, CV_ADAPTIVE_THRESH_GAUSSIAN_C) + + # Retrieval mode + assert_equal(0, CV_RETR_EXTERNAL) + assert_equal(1, CV_RETR_LIST) + assert_equal(2, CV_RETR_CCOMP) + assert_equal(3, CV_RETR_TREE) + + # Approximation method + assert_equal(0, CV_CHAIN_CODE) + assert_equal(1, CV_CHAIN_APPROX_NONE) + assert_equal(2, CV_CHAIN_APPROX_SIMPLE) + assert_equal(3, CV_CHAIN_APPROX_TC89_L1) + assert_equal(4, CV_CHAIN_APPROX_TC89_KCOS) + assert_equal(5, CV_LINK_RUNS) + + # Termination criteria for iterative algorithms + assert_equal(1, CV_TERMCRIT_ITER) + assert_equal(1, CV_TERMCRIT_NUMBER) + assert_equal(2, CV_TERMCRIT_EPS) + + # Hough transform methods + assert_equal(0, CV_HOUGH_STANDARD) + assert_equal(1, CV_HOUGH_PROBABILISTIC) + assert_equal(2, CV_HOUGH_MULTI_SCALE) + assert_equal(3, CV_HOUGH_GRADIENT) + + # Inpaint method + assert_equal(0, CV_INPAINT_NS) + assert_equal(1, CV_INPAINT_TELEA) + + # Match tempalte method + assert_equal(0, CV_TM_SQDIFF) + assert_equal(1, CV_TM_SQDIFF_NORMED) + assert_equal(2, CV_TM_CCORR) + assert_equal(3, CV_TM_CCORR_NORMED) + assert_equal(4, CV_TM_CCOEFF) + assert_equal(5, CV_TM_CCOEFF_NORMED) + + # Comparison method + assert_equal(1, CV_CONTOURS_MATCH_I1) + assert_equal(2, CV_CONTOURS_MATCH_I2) + assert_equal(3, CV_CONTOURS_MATCH_I3) + + # Fundamental matrix computing methods + assert_equal(1, CV_FM_7POINT) + assert_equal(2, CV_FM_8POINT) + assert_equal(8, CV_FM_RANSAC) + assert_equal(4, CV_FM_LMEDS) + + # Flags of window + assert_equal(0, CV_WINDOW_NORMAL) + assert_equal(1, CV_WINDOW_AUTOSIZE) + assert_equal(4096, CV_WINDOW_OPENGL) + + # Object detection mode + assert_equal(1, CV_HAAR_DO_CANNY_PRUNING) + + # Interpolation methods + assert_equal(0, CV_INTER_NN) + assert_equal(1, CV_INTER_LINEAR) + assert_equal(2, CV_INTER_CUBIC) + assert_equal(3, CV_INTER_AREA) + + # Warp affine optional flags + assert_equal(8, CV_WARP_FILL_OUTLIERS) + assert_equal(16, CV_WARP_INVERSE_MAP) + + # SVD operation flags + assert_equal(1, CV_SVD_MODIFY_A) + assert_equal(2, CV_SVD_U_T) + assert_equal(4, CV_SVD_V_T) + + # Histogram representation format + assert_equal(0, CV_HIST_ARRAY) + assert_equal(1, CV_HIST_SPARSE) + assert_equal(1, CV_HIST_TREE) + assert_equal(1, CV_HIST_UNIFORM) + + # Histogram comparison method + assert_equal(0, CV_COMP_CORREL) + assert_equal(1, CV_COMP_CHISQR) + assert_equal(2, CV_COMP_INTERSECT) + assert_equal(3, CV_COMP_BHATTACHARYYA) + end + + def test_symbols + # Depths + assert_equal(0, DEPTH[:cv8u]) + assert_equal(1, DEPTH[:cv8s]) + assert_equal(2, DEPTH[:cv16u]) + assert_equal(3, DEPTH[:cv16s]) + assert_equal(4, DEPTH[:cv32s]) + assert_equal(5, DEPTH[:cv32f]) + assert_equal(6, DEPTH[:cv64f]) + + # Inversion methods + assert_equal(0, INVERSION_METHOD[:lu]) + assert_equal(1, INVERSION_METHOD[:svd]) + assert_equal(2, INVERSION_METHOD[:svd_sym]) + assert_equal(2, INVERSION_METHOD[:svd_symmetric]) + + # Homography calculation methods + assert_equal(0, HOMOGRAPHY_CALC_METHOD[:all]) + assert_equal(4, HOMOGRAPHY_CALC_METHOD[:lmeds]) + assert_equal(8, HOMOGRAPHY_CALC_METHOD[:ransac]) + + # Anti aliasing flags + assert_equal(16, CONNECTIVITY[:aa]) + assert_equal(16, CONNECTIVITY[:anti_alias]) + + # Retrieval modes + assert_equal(0, RETRIEVAL_MODE[:external]) + assert_equal(1, RETRIEVAL_MODE[:list]) + assert_equal(2, RETRIEVAL_MODE[:ccomp]) + assert_equal(3, RETRIEVAL_MODE[:tree]) + + # Approximation methods + assert_equal(0, APPROX_CHAIN_METHOD[:code]) + assert_equal(1, APPROX_CHAIN_METHOD[:approx_none]) + assert_equal(2, APPROX_CHAIN_METHOD[:approx_simple]) + assert_equal(3, APPROX_CHAIN_METHOD[:approx_tc89_l1]) + assert_equal(4, APPROX_CHAIN_METHOD[:approx_tc89_kcos]) + + # Approximation methods (polygon) + assert_equal(0, APPROX_POLY_METHOD[:dp]) + + # Match template methods + assert_equal(0, MATCH_TEMPLATE_METHOD[:sqdiff]) + assert_equal(1, MATCH_TEMPLATE_METHOD[:sqdiff_normed]) + assert_equal(2, MATCH_TEMPLATE_METHOD[:ccorr]) + assert_equal(3, MATCH_TEMPLATE_METHOD[:ccorr_normed]) + assert_equal(4, MATCH_TEMPLATE_METHOD[:ccoeff]) + assert_equal(5, MATCH_TEMPLATE_METHOD[:ccoeff_normed]) + + # Structuring element shapes + assert_equal(0, STRUCTURING_ELEMENT_SHAPE[:rect]) + assert_equal(1, STRUCTURING_ELEMENT_SHAPE[:cross]) + assert_equal(2, STRUCTURING_ELEMENT_SHAPE[:ellipse]) + assert_equal(100, STRUCTURING_ELEMENT_SHAPE[:custom]) + + # Types of morphological operations + assert_equal(2, MORPHOLOGICAL_OPERATION[:open]) + assert_equal(3, MORPHOLOGICAL_OPERATION[:close]) + assert_equal(4, MORPHOLOGICAL_OPERATION[:gradient]) + assert_equal(5, MORPHOLOGICAL_OPERATION[:tophat]) + assert_equal(6, MORPHOLOGICAL_OPERATION[:blackhat]) + + # Types of the smoothing + assert_equal(0, SMOOTHING_TYPE[:blur_no_scale]) + assert_equal(1, SMOOTHING_TYPE[:blur]) + assert_equal(2, SMOOTHING_TYPE[:gaussian]) + assert_equal(3, SMOOTHING_TYPE[:median]) + assert_equal(4, SMOOTHING_TYPE[:bilateral]) + + # Thresholding types + assert_equal(0, THRESHOLD_TYPE[:binary]) + assert_equal(1, THRESHOLD_TYPE[:binary_inv]) + assert_equal(2, THRESHOLD_TYPE[:trunc]) + assert_equal(3, THRESHOLD_TYPE[:tozero]) + assert_equal(4, THRESHOLD_TYPE[:tozero_inv]) + assert_equal(8, THRESHOLD_TYPE[:otsu]) + + # Hough transform methods + assert_equal(0, HOUGH_TRANSFORM_METHOD[:standard]) + assert_equal(1, HOUGH_TRANSFORM_METHOD[:probabilistic]) + assert_equal(2, HOUGH_TRANSFORM_METHOD[:multi_scale]) + assert_equal(3, HOUGH_TRANSFORM_METHOD[:gradient]) + + # Inpaint method + assert_equal(0, INPAINT_METHOD[:ns]) + assert_equal(1, INPAINT_METHOD[:telea]) + + # Comparison method + assert_equal(1, COMPARISON_METHOD[:i1]) + assert_equal(2, COMPARISON_METHOD[:i2]) + assert_equal(3, COMPARISON_METHOD[:i3]) + end + + def test_cvt_color_funcs + mat_1ch = CvMat.new(1, 1, :cv8u, 1) + mat_1ch[0] = CvScalar.new(10) + + mat_3ch = CvMat.new(1, 1, :cv8u, 3) + mat_3ch[0] = CvScalar.new(10, 20, 30) + + mat_4ch = CvMat.new(1, 1, :cv8u, 4) + mat_4ch[0] = CvScalar.new(10, 20, 30, 40) + + gray_rgb = (0.299 * mat_3ch[0][0] + 0.587 * mat_3ch[0][1] + 0.114 * mat_3ch[0][2]).round + gray_bgr = (0.299 * mat_3ch[0][2] + 0.587 * mat_3ch[0][1] + 0.114 * mat_3ch[0][0]).round + + # RGB(A) <=> RGB(A) + [mat_3ch.BGR2BGRA, mat_3ch.RGB2RGBA].each { |m| + assert_equal(CvMat, m.class) + assert_equal(4, m.channel) + assert_cvscalar_equal(CvScalar.new(10, 20, 30, 255), m[0]) + } + [mat_3ch.BGR2RGBA, mat_3ch.RGB2BGRA].each { |m| + assert_equal(CvMat, m.class) + assert_equal(4, m.channel) + assert_cvscalar_equal(CvScalar.new(30, 20, 10, 255), m[0]) + } + [mat_4ch.BGRA2BGR, mat_4ch.RGBA2RGB].each { |m| + assert_equal(CvMat, m.class) + assert_equal(3, m.channel) + assert_cvscalar_equal(CvScalar.new(10, 20, 30, 0), m[0]) + } + [mat_4ch.RGBA2BGR, mat_4ch.BGRA2RGB].each { |m| + assert_equal(CvMat, m.class) + assert_equal(3, m.channel) + assert_cvscalar_equal(CvScalar.new(30, 20, 10, 0), m[0]) + } + [mat_3ch.BGR2RGB, mat_3ch.RGB2BGR].each { |m| + assert_equal(CvMat, m.class) + assert_equal(3, m.channel) + assert_cvscalar_equal(CvScalar.new(30, 20, 10, 0), m[0]) + } + [mat_4ch.BGRA2RGBA, mat_4ch.RGBA2BGRA].each { |m| + assert_equal(CvMat, m.class) + assert_equal(4, m.channel) + assert_cvscalar_equal(CvScalar.new(30, 20, 10, 40), m[0]) + } + + # RGB <=> GRAY + [mat_3ch.BGR2GRAY, mat_4ch.BGRA2GRAY].each { |m| + assert_equal(CvMat, m.class) + assert_equal(1, m.channel) + assert_cvscalar_equal(CvScalar.new(gray_bgr, 0, 0, 0), m[0]) + } + [mat_3ch.RGB2GRAY, mat_4ch.RGBA2GRAY].each { |m| + assert_equal(CvMat, m.class) + assert_equal(1, m.channel) + assert_cvscalar_equal(CvScalar.new(gray_rgb, 0, 0, 0), m[0]) + } + [mat_1ch.GRAY2BGR, mat_1ch.GRAY2RGB].each { |m| + assert_equal(CvMat, m.class) + assert_equal(3, m.channel) + assert_cvscalar_equal(CvScalar.new(10, 10, 10, 0), m[0]) + } + [mat_1ch.GRAY2BGRA, mat_1ch.GRAY2RGBA].each { |m| + assert_equal(CvMat, m.class) + assert_equal(4, m.channel) + assert_cvscalar_equal(CvScalar.new(10, 10, 10, 255), m[0]) + } + + img_3ch = IplImage.new(1, 1, :cv8u, 3) + assert_equal(IplImage, img_3ch.BGR2GRAY.class) + + flunk('FIXME: Most cvtColor functions are not tested yet.') + end + + def test_build_information + s = build_information + assert_equal(String, s.class) + assert(s =~ /^\s+General configuration for OpenCV #{CV_VERSION}/) + end +end -require 'opencv' diff --git a/test/test_pointset.rb b/test/test_pointset.rb new file mode 100755 index 00000000..ded129a8 --- /dev/null +++ b/test/test_pointset.rb @@ -0,0 +1,128 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::PointSet +class TestPointSet < OpenCVTestCase + def setup + mat0 = create_cvmat(128, 128, :cv8u, 1) { |j, i| + (j - 64) ** 2 + (i - 64) ** 2 <= (32 ** 2) ? CvColor::White : CvColor::Black + } + @contour1 = mat0.find_contours + @contour2 = CvContour.new + end + + def test_contour_area + assert_equal(3118, @contour1.contour_area.to_i) + + s = CvSlice.new(0, @contour1.size / 2) + assert_equal(1527, @contour1.contour_area(s).to_i) + + assert_raise(TypeError) { + @contour1.contour_area(DUMMY_OBJ) + } + assert_raise(CvStsBadArg) { + @contour2.contour_area + } + end + + def test_fit_ellipse2 + box = @contour1.fit_ellipse2 + + center = box.center + assert_equal(64, center.x.to_i) + assert_equal(64, center.y.to_i) + + size = box.size + assert_in_delta(63, size.width, 1.0) + assert_in_delta(63, size.height, 1.0) + + angle = [box.angle, 180 - box.angle].min + assert_in_delta(0, angle, 0.1) + + assert_raise(CvStsBadSize) { + @contour2.fit_ellipse2 + } + end + + def test_convex_hull2 + [@contour1.convex_hull2, @contour1.convex_hull2(true)].each { |hull| + assert_equal(36, hull.size) + assert_equal(CvContour, hull.class) + assert_equal(CvPoint, hull[0].class) + assert_equal(32, hull[0].x) + assert_equal(64, hull[0].y) + } + + hull = @contour1.convex_hull2(false) + assert_equal(36, hull.size) + assert_equal(CvContour, hull.class) + assert_equal(CvPoint, hull[0].class) + assert_equal(96, hull[0].x) + assert_equal(64, hull[0].y) + + @contour1.convex_hull2(DUMMY_OBJ) + end + + def test_check_contour_convexity + assert_false(@contour1.check_contour_convexity) + end + + def test_convexity_defects + hull = @contour1.convex_hull2(true, false) + defects = @contour1.convexity_defects(hull) + assert_equal(CvSeq, defects.class) + assert_equal(CvConvexityDefect, defects[0].class) + assert_equal(32, defects.size) + + d = defects[0] + assert_equal(33, d.start.x) + assert_equal(57, d.start.y) + assert_equal(33, d.depth_point.x) + assert_equal(63, d.depth_point.y) + assert_equal(32, d.end.x) + assert_equal(64, d.end.y) + assert_in_delta(0.8485, d.depth, 0.001) + + assert_raise(TypeError) { + @contour1.convexity_defects(DUMMY_OBJ) + } + end + + def test_min_area_rect2 + box = @contour1.min_area_rect2 + + assert_equal(CvBox2D, box.class) + center = box.center + assert_equal(64, center.x.to_i) + assert_equal(64, center.y.to_i) + + size = box.size + assert_in_delta(63.356, size.width, 0.001) + assert_in_delta(63.356, size.height, 0.001) + assert_in_delta(-81.30, box.angle, 1.0) + + flunk('FIXME: Currently PointSet#min_area_rect2 causes segmentation fault when "self" is invalid.') + assert_raise(CvStsBadSize) { + @contour2.min_area_rect2 + } + end + + def test_min_enclosing_circle + circle = @contour1.min_enclosing_circle + assert_equal(CvCircle32f, circle.class) + center = circle.center + assert_equal(64, center.x.to_i) + assert_equal(64, center.y.to_i) + assert_in_delta(32.959, circle.radius, 0.001) + + assert_raise(CvStsBadSize) { + @contour2.min_enclosing_circle + } + end +end + diff --git a/test/test_preliminary.rb b/test/test_preliminary.rb new file mode 100755 index 00000000..feaead06 --- /dev/null +++ b/test/test_preliminary.rb @@ -0,0 +1,130 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'digest/md5' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests to run first; check the handful of basic operations that the later tests rely on +class TestPreliminary < OpenCVTestCase + def test_assert_array_equal + assert_array_equal([1, 2, 3, 4], [1, 2, 3, 4]) + + # Uncomment the following line to check the fail case + # assert_array_equal([1, 2, 3, 4], [1, 2, 3, 0]) + end + + def test_assert_cvscalar_equal + assert_cvscalar_equal(CvScalar.new(1, 2, 3, 4), CvScalar.new(1, 2, 3, 4)) + assert_cvscalar_equal(CvScalar.new(0.1, 0.2, 0.3, 0.4), CvScalar.new(0.1, 0.2, 0.3, 0.4)) + + # Uncomment the following lines to check the fail cases + # assert_cvscalar_equal(CvScalar.new(1, 2, 3, 4), CvScalar.new(1, 2, 3, 0)) + # assert_cvscalar_equal(CvScalar.new(0.1, 0.2, 0.3, 0.4), CvScalar.new(0.1, 0.2, 0.3, 0.0)) + end + + def test_assert_in_delta + assert_in_delta(1, 0.9999, 0.1) + assert_in_delta(CvScalar.new(1, 2, 3, 4), CvScalar.new(1.01, 2.01, 3.01, 4.01), 0.1) + assert_in_delta(CvScalar.new(1, 2, 3, 4), [1.01, 2.01, 3.01, 4.01], 0.1) + assert_in_delta([1, 2, 3, 4], CvScalar.new(1.01, 2.01, 3.01, 4.01), 0.1) + assert_in_delta([1, 2, 3, 4], [1.01, 2.01, 3.01, 4.01], 0.1) + + # Uncomment the following lines to check the fail cases + # assert_in_delta(1, 0.009, 0.1) + # assert_in_delta(CvScalar.new(1, 2, 3, 4), CvScalar.new(1.01, 2.01, 3.01, 4.01), 0.001) + # assert_in_delta(CvScalar.new(1, 2, 3, 4), [1.01, 2.01, 3.01, 4.01], 0.001) + # assert_in_delta([1, 2, 3, 4], CvScalar.new(1.01, 2.01, 3.01, 4.01), 0.001) + # assert_in_delta([1, 2, 3, 4], [1.01, 2.01, 3.01, 4.01], 0.001) + end + + def test_assert_each_cvscalar + mat1 = CvMat.new(5, 5, :cv32f, 4) + mat2 = CvMat.new(5, 5, :cv32f, 4) + c = 0 + mat1.height.times { |j| + mat1.width.times { |i| + mat1[j, i] = CvScalar.new(c * 0.1, c * 0.2, c * 0.3, c * 0.4) + mat2[j, i] = CvScalar.new(c, c, c, c) + c += 1 + } + } + + assert_each_cvscalar(mat1, 0.001) { |j, i, n| + CvScalar.new(n * 0.1, n * 0.2, n * 0.3, n * 0.4) + } + assert_each_cvscalar(mat2) { |j, i, n| + CvScalar.new(n, n, n, n) + } + + # Uncomment the following lines to check the fail cases + # assert_each_cvscalar(mat1, 0.001) { |j, i, n| + # CvScalar.new(n * 0.1, n * 0.2, n * 0.3, 0) + # } + # assert_each_cvscalar(mat1, 0.001) { |j, i, n| + # CvScalar.new(1, 2, 3, 4) + # } + # assert_each_cvscalar(mat2) { |j, i, n| + # CvScalar.new(n * 0.1, n * 0.2, n * 0.3, 0) + # } + # assert_each_cvscalar(mat2) { |j, i, n| + # CvScalar.new(1, 2, 3, 0) + # } + end + + + def test_create_cvmat + mat = create_cvmat(3, 4) + assert_equal(3, mat.height) + assert_equal(4, mat.width) + assert_equal(:cv8u, mat.depth) + assert_equal(4, mat.channel) + c = 0 + mat.height.times { |j| + mat.width.times { |i| + s = CvScalar.new(c + 1, c + 1, c + 1, c + 1) + assert_cvscalar_equal(s, mat[j, i]) + c += 1 + } + } + + mat = create_cvmat(2, 3, :cv16s, 2) + assert_equal(2, mat.height) + assert_equal(3, mat.width) + assert_equal(:cv16s, mat.depth) + assert_equal(2, mat.channel) + c = 0 + mat.height.times { |j| + mat.width.times { |i| + s = CvScalar.new(c + 1, c + 1, 0, 0) + assert_cvscalar_equal(s, mat[j, i]) + c += 1 + } + } + + mat = create_cvmat(2, 3, :cv16u, 3) { |j, i, cnt| + n = j + i + cnt + CvScalar.new(n, n, n, 0) + } + assert_equal(2, mat.height) + assert_equal(3, mat.width) + assert_equal(:cv16u, mat.depth) + assert_equal(3, mat.channel) + c = 0 + mat.height.times { |j| + mat.width.times { |i| + n = j + i + c + assert_cvscalar_equal(CvScalar.new(n, n, n, 0), mat[j, i]) + c += 1 + } + } + end + + def test_types + assert_equal(IplImage.new(7, 5, CV_8U, 1).class, IplImage) + assert_equal(CvMat.new(5, 7, CV_32F).class, CvMat) + end +end + diff --git a/test/test_trackbar.rb b/test/test_trackbar.rb new file mode 100755 index 00000000..56dd9643 --- /dev/null +++ b/test/test_trackbar.rb @@ -0,0 +1,47 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV +include GUI + +# Tests for OpenCV::Trackbar +class TestTrackbar < OpenCVTestCase + def setup + @trackbar1 = Trackbar.new('trackbar1', 100) {} + @trackbar2 = Trackbar.new('trackbar1', 100, 1) {} + end + + def test_initialize + assert_not_nil(Trackbar.new('trackbar', 100, 1) {}) + assert_not_nil(Trackbar.new('trackbar', 100) {}) + block = proc {} + assert_not_nil(Trackbar.new('trackbar', 100, 1, &block)) + assert_not_nil(Trackbar.new('trackbar', 100, &block)) + + assert_raise(TypeError) { + Trackbar.new(123, 100, 1) {} + } + assert_raise(ArgumentError) { + Trackbar.new('trackbar', 100, 1) + } + end + + def test_name + assert_equal('trackbar1', @trackbar1.name) + end + + def test_max + assert_equal(100, @trackbar1.max) + end + + def test_value + assert_equal(0, @trackbar1.value) + assert_equal(1, @trackbar2.value) + @trackbar1.value = 50 + assert_equal(50, @trackbar1.value) + end +end + diff --git a/test/test_window.rb b/test/test_window.rb new file mode 100755 index 00000000..9236f0cf --- /dev/null +++ b/test/test_window.rb @@ -0,0 +1,115 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8 -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV +include GUI + +# Tests for OpenCV::Window +class TestWindow < OpenCVTestCase + def setup + @window1 = Window.new('window1') + @window2 = Window.new('window2', CV_WINDOW_AUTOSIZE) + @window3 = Window.new('window3', 0) + end + + def teardown + Window::destroy_all + end + + def test_initialize + [Window.new('w1'), Window.new('w2', CV_WINDOW_AUTOSIZE), Window.new('w3', 0)].each { |w| + assert_not_nil(w) + assert_equal(Window, w.class) + } + + assert_raise(TypeError) { + Window.new('w4', 'foobar') + } + + assert_raise(StandardError) { + Window.new('w5') + Window.new('w5') + } + end + + def test_alive + assert(@window1.alive?) + @window1.destroy + assert(!(@window1.alive?)) + end + + def test_destroy + @window1.destroy + assert(!(@window1.alive?)) + end + + def test_destroy_all + Window::destroy_all + assert(!(@window1.alive?)) + assert(!(@window2.alive?)) + assert(!(@window3.alive?)) + end + + def test_resize + @window1.resize(CvSize.new(10, 20)) + @window2.resize(100, 200) + assert_raise(ArgumentError) { + @window3.resize + } + + # Uncomment the following lines to show the results + # @window1.show(CvMat.new(10, 20)) + # @window1.resize(100, 200) + # GUI::wait_key + end + + def test_move + @window1.move(CvPoint.new(10, 20)) + @window2.move(100, 200) + assert_raise(ArgumentError) { + @window3.move + } + + # Uncomment the following lines to show the results + # @window1.show(CvMat.new(10, 20)) + # @window2.show(CvMat.new(100, 200)) + # GUI::wait_key + end + + def test_show_image + img = IplImage.load(FILENAME_CAT, CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR) + @window1.show_image(img) + @window2.show(img) # Alias + + # Uncomment the following lines to show the results + # GUI::wait_key + end + + def test_set_trackbar + tr1 = @window1.set_trackbar('trackbar1', 100) { |value| + puts value + } + assert_equal(Trackbar, tr1.class) + + trackbar2 = Trackbar.new('trackbar2', 10, 1) {} + tr2 = @window2.set_trackbar(trackbar2) + assert_equal(Trackbar, tr2.class) + end + + def test_set_mouseevent + @window1.set_mouse_callback { |mouse| + e = "#{mouse.x}, #{mouse.y} : #{mouse.event} : " + e << "" if mouse.left_button? + e << "" if mouse.right_button? + e << "" if mouse.middle_button? + e << "[CTRL]" if mouse.ctrl_key? + e << "[SHIFT]" if mouse.shift_key? + e << "[ALT]" if mouse.alt_key? + puts e + } + end +end + diff --git a/yard_extension.rb b/yard_extension.rb new file mode 100644 index 00000000..46f68a3a --- /dev/null +++ b/yard_extension.rb @@ -0,0 +1,5 @@ +require 'yard' + +YARD::Tags::Library.define_tag('OpenCV function', :opencv_func) +YARD::Tags::Library.visible_tags.place(:opencv_func).before(:abstract) +