tins-1.32.1/0000755000004100000410000000000014353307475012616 5ustar www-datawww-datatins-1.32.1/COPYING0000644000004100000410000000202114353307475013644 0ustar www-datawww-dataCopyright (c) 2010 Florian Frank Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. tins-1.32.1/README.md0000644000004100000410000000670414353307475014104 0ustar www-datawww-data# Tins - Useful tools library in Ruby ## Description Non yet. ## Badges [![Code Climate](https://codeclimate.com/github/flori/tins.png)](https://codeclimate.com/github/flori/tins) [![Code Coverage](https://codeclimate.com/github/flori/tins/coverage.png)](https://codeclimate.com/github/flori/tins) ## Changes * 2018-11-14 Release 1.20.2 - Fix ~x options * 2018-11-14 Release 1.20.1 - Add disabling boolean options in Tins::GO#go method. * 2018-11-14 Release 1.20.0 - Support default arguments in Tins::GO#go method. * 2018-11-07 Release 1.19.0 - Allow annotations without arguments * 2018-11-02 Release 1.18.0 - `thread_local` and `thread_global` with default block * 2018-10-15 Release 1.17.0 - Add Tins::TempIO::Enum class to wrap `temp_io` into Enumerator. * 2017-12-05 Release 1.16.3 - Improve `temp_io` method by not changing working dir. * 2017-12-05 Release 1.16.2 - Improve `temp_io` method with a given name. * 2017-12-05 Release 1.16.1 - Improve `temp_io` method with block * 2017-11-29 Release 1.16.0 - Prove `temp_io` method with block * 2017-06-29 Release 1.15.0 - Add support for smart duration formats with %D directive * 2017-05-16 Release 1.14.0 - Add visit proc to determine if file should be visited. * 2017-05-14 Release 1.13.3 - Fix some debugging warnings * 2017-02-03 Release 1.13.2 - Fix test on older rubies * 2016-11-23 Release 1.13.1 - Fix comparibility of Tins::Duration instances * 2016-11-23 Release 1.13.0 - Add expose method mostly for testing hidden methods. * 2016-08-04 Release 1.12.0 - Add Tins::Unit.parse? method to check for units in strings. * 2016-07-12 Release 1.11.0 - Provide Tins::Unit.format and Tins::Unit.parse methods. * 2016-05-25 Release 1.10.2 - Avoid some warnings. * 2016-04-15 Release 1.10.1 - Fix bug in go if a concatenated argument comes last. * 2016-04-12 Release 1.10.0 - Support mixed rest arguments in go argument parsing. * 2016-03-10 Release 1.9.0 - Add Tins::Duration for displaying durations. * 2016-01-18 Release 1.8.2 - Implement Tins::StringVersion::Version#dup and Tins::StringVersion::Version#clone. * 2015-12-03 Release 1.8.1 - Remove some backports already existant in the newer supported rubies. * 2015-12-01 Release 1.8.0 - Add `foo_of` and `foo_annotations` methods to instances of classes with annotated methods. * 2015-11-09 Release 1.7.0 - Officially require ruby >= 2.0 and use new hash syntax. - New feature attempt: sleep:-30 sleeps upto 30 seconds while retrying with an exponential waiting pattern. - Remove rotate and shuffle, recent rubies all support them. - Add an object oriented view on method signatures and use it to create method descriptions. * 2015-08-13 Release 1.6.0 - Add complete method for readline completion * 2015-06-21 Release 1.5.4 - Avoid %i syntax for now * 2015-06-17 Release 1.5.3 - Make it run on 1.9 again. - Avoid a warning in Time.dummy implementation. * 2015-05-27 Release 1.5.2 - Fix parameter naming for c-methods in method descriptions. * 2015-04-24 Release 1.5.0/1.5.1 - Implement bump logic for StringVersion * 2015-04-23 Release 1.4.0 - Add implement module helper method. * 2015-03-03 Release 1.3.5 - Don't automatically include #to method into Object, this can lead to some confusion. * 2015-02-04 Release 1.3.4 - Add some default alphabets to Tins::Token, e. g. Base64 - Add changes to Readme ## Author Florian Frank mailto:flori@ping.de ## License This software is licensed under the MIT (Expat) license. tins-1.32.1/tests/0000755000004100000410000000000014353307475013760 5ustar www-datawww-datatins-1.32.1/tests/unit_test.rb0000644000004100000410000000451514353307475016330 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class UnitTest < Test::Unit::TestCase include Tins::Unit def test_prefixes assert_equal %i[ foo ], prefixes(%i[ foo ]) assert_equal Tins::Unit::PREFIX_LC, prefixes(1000) assert_equal Tins::Unit::PREFIX_LC, prefixes(:lc) assert_equal Tins::Unit::PREFIX_LC, prefixes(:lowercase) assert_equal Tins::Unit::PREFIX_UC, prefixes(1024) assert_equal Tins::Unit::PREFIX_UC, prefixes(:uc) assert_equal Tins::Unit::PREFIX_UC, prefixes(:uppercase) assert_equal Tins::Unit::PREFIX_F, prefixes(0.001) assert_equal Tins::Unit::PREFIX_F, prefixes(:f) assert_equal Tins::Unit::PREFIX_F, prefixes(:fraction) assert_equal nil, prefixes(:nix) end def test_0_format assert_equal '0 b', format(0, format: '%d %U') end def test_format_multipliers assert_equal '23 Kb', format(23 * 1024, format: '%d %U') assert_equal '-23 Kb', format(-23 * 1024, format: '%d %U') assert_equal '23.1 Kb', format(23 * 1024 + 111, format: '%.1f %U') assert_equal 'Kbps: 23', format(23 * 1024, format: '%U: %d', unit: 'bps') assert_equal 'kbps: 23.12', format(23 * 1000 + 120, prefix: 1000, format: '%U: %.2f', unit: 'bps') end def test_format_fractions assert_equal '0.123 mS', format(0.000_123, format: '%.3f %U', prefix: 0.001, unit: ?S) assert_equal '0.123 µF', format(0.000_000_123, format: '%.3f %U', prefix: :f, unit: ?F) end def test_parse assert_in_delta 17_301_504, parse('16.5 Mb').to_i, 1e-5 assert_in_delta 16_500_000, parse('16.5 mbps', unit: 'bps').to_i, 1e-5 assert_in_delta 0.1234e-5, parse('1.234 µS', unit: ?S, prefix: :f).to_s, 1e-5 assert_raise(ParserError) { parse('16.5 nix', unit: ?b) } assert_raise(ParserError) { parse('nix Mb') } assert_in_delta 17_301_504, parse('16.5 % Mb', format: '%f %% %U').to_i, 1e-5 assert_raise(ParserError) { parse('16.5 Mb', format: '%f %% %U') } assert_raise(ParserError) { parse('16.5 Mb foo', format: '%f %U') } assert_raise(ParserError) { parse('16.5 Mb', format: '%f %U foo') } end def test_parse_predicate assert_in_delta 17_301_504, parse?('16.5 Mb').to_i, 1e-5 assert_nil parse?('16.5 nix', unit: ?b) end end end tins-1.32.1/tests/hash_union_test.rb0000644000004100000410000000173514353307475017505 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class HashUnionTest < Test::Unit::TestCase class HashLike1 def to_hash { 'foo' => true } end end class HashLike2 def to_h { 'foo' => true } end end def test_union defaults = { 'foo' => true, 'bar' => false, 'quux' => nil } hash = { 'foo' => false } assert_equal [ ['bar', false], ['foo', false], ['quux', nil] ], (hash | defaults).sort hash |= defaults assert_equal [ ['bar', false], ['foo', false], ['quux', nil] ], hash.sort hash = { 'foo' => false } hash |= { 'quux' => true, 'baz' => 23, } | defaults assert_equal [ ['bar', false], [ 'baz', 23 ], ['foo', false], ['quux', true] ], hash.sort end def test_hash_conversion assert_equal({ 'foo' => true }, { } | HashLike1.new) assert_equal({ 'foo' => true }, { } | HashLike2.new) end end end tins-1.32.1/tests/file_binary_test.rb0000644000004100000410000000347114353307475017634 0ustar www-datawww-datarequire 'test_helper' require 'tempfile' require 'tins/xt' module Tins class TinsFileBinaryTest < Test::Unit::TestCase def test_ascii_buffer_size write_file do |file| file.write "A" * 10 + "\x00" assert_equal true, file.ascii?(buffer_size: 10) assert_equal true, File.ascii?(file.path, buffer_size: 10) assert_equal false, file.binary?(buffer_size: 10) assert_equal false, File.binary?(file.path, buffer_size: 10) end end def test_binary write_file do |file| file.write "A" * 69 + "\x01" * 31 assert_equal true, file.binary? assert_equal true, File.binary?(file.path) assert_equal false, file.ascii? assert_equal false, File.ascii?(file.path) end end def test_ascii_offset write_file do |file| file.write "\x01" * 31 + "A" * 70 assert_equal false, file.binary?(offset: 1) assert_equal false, File.binary?(file.path, offset: 1) assert_equal true, file.ascii?(offset: 1) assert_equal true, File.ascii?(file.path, offset: 1) end end def test_binary_zero write_file do |file| file.write "A" * 50 + "\0" + "A" * 49 assert_equal true, file.binary? assert_equal true, File.binary?(file.path) assert_equal false, file.ascii? assert_equal false, File.ascii?(file.path) end end def test_ascii write_file do |file| file.write "A" * 100 assert_equal false, file.binary? assert_equal false, File.binary?(file.path) assert_equal true, file.ascii? assert_equal true, File.ascii?(file.path) end end private def write_file File.open(File.join(Dir.tmpdir, "temp.#$$"), 'wb+') do |file| yield file end end end end tins-1.32.1/tests/limited_test.rb0000644000004100000410000000070014353307475016770 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class LimitedTest < Test::Unit::TestCase def test_limited count = {} limited = Tins::Limited.new(5) 5.times do limited.execute do count[Thread.current] = true sleep 1 end end until count.size >= 5 sleep 0.1 end assert_equal 5, count.keys.uniq.size assert_equal 5, limited.wait.size end end end tins-1.32.1/tests/method_description_test.rb0000644000004100000410000000507714353307475021240 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class MethodDescriptionTest < Test::Unit::TestCase class A def foo end def self.foo end end def test_static_nonstatic assert_equal 'Tins::MethodDescriptionTest::A#foo()', A.instance_method(:foo).to_s assert_equal '#', A.instance_method(:foo).inspect assert_equal 'Tins::MethodDescriptionTest::A.foo()', A.method(:foo).to_s assert_equal '#', A.method(:foo).inspect end class B def foo(x, y = 1, *r, &b) end def bar(x, y = 2, *r, &b) end def bar2(x, z = 2, *r, &b) end def baz(x, y = 2, z = 3, *r, &b) end end def test_standard_parameters_namespace assert_equal 'Tins::MethodDescriptionTest::B#foo(x,y=?,*r,&b)', B.instance_method(:foo).to_s end def test_standard_parameters_name assert_equal 'foo(x,y=?,*r,&b)', B.instance_method(:foo).description(style: :name) end def test_standard_parameters_signature assert_kind_of Tins::MethodDescription::Signature, B.instance_method(:foo).signature end def test_signature_equalitites assert_equal( B.instance_method(:foo).signature, B.instance_method(:bar).signature ) assert_equal( B.instance_method(:foo).signature, B.instance_method(:bar2).signature ) assert_false\ B.instance_method(:foo).signature.eql?( B.instance_method(:bar2).signature ) assert_operator( B.instance_method(:foo).signature, :===, B.instance_method(:bar2) ) assert_not_equal( B.instance_method(:bar).signature, B.instance_method(:baz).signature ) end def test_a_cstyle_method_from_hash assert_equal "Hash#store(x1,x2)", ({}.method(:store).description) end class C def foo(x, k: true, &b) end def bar(x, **k, &b) end end def test_keyword_parameters assert_equal 'Tins::MethodDescriptionTest::C#foo(x,k:?,&b)', C.instance_method(:foo).to_s assert_equal 'Tins::MethodDescriptionTest::C#bar(x,**k,&b)', C.instance_method(:bar).to_s end if RUBY_VERSION >= "2.1" eval %{ class D def foo(x, k:, &b) end end def test_keyword_parameters_required assert_equal 'Tins::MethodDescriptionTest::D#foo(x,k:,&b)', D.instance_method(:foo).to_s end } end end end tins-1.32.1/tests/range_plus_test.rb0000644000004100000410000000050114353307475017477 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class RangePlustTest < Test::Unit::TestCase def test_range_plus assert_equal [], (0...0) + (0...0) assert_equal [ 0 ], (0..0) + (0...0) assert_equal [ 0, 0 ], (0..0) + (0..0) assert_equal((1..5).to_a, (1...3) + (3..5)) end end end tins-1.32.1/tests/subhash_test.rb0000644000004100000410000000214014353307475016776 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class SubhashTest < Test::Unit::TestCase require 'tins/xt/subhash' def test_subhash h = { 'foo1' => 1, 'foo2' => 2, 'bar666' => 666 } assert_equal [ [ 'bar666', 666 ] ], h.subhash(/\Abar/).to_a assert h.subhash(/\Abaz/).empty? assert_equal [ [ 'foo1', 1 ], [ 'foo2', 2 ] ], h.subhash(/\Afoo\d/).sort assert_equal [ [ 'foo2', 2 ] ], h.subhash('foo2').to_a end def test_subhash_bang h = { 'foo1' => 1, 'foo2' => 2, 'bar666' => 666 } h.subhash!('foo2') assert_equal [ [ 'foo2', 2 ] ], h.to_a end def test_subhash_with_block h = { 'foo1' => 1, 'foo2' => 2, 'bar666' => 666 } assert h.subhash(/\Abaz/) { :foo }.empty? assert_equal [ [ 'foo1', 1 ], [ 'foo2', 2 ] ], h.subhash(/\Afoo(\d)/) { |_,_,m| Integer(m[1]) }.to_a.sort end def test_subhash_with_default_proc hash = Hash.new { |h, k| h[k] = :foo } hash.update('foo' => 1, 'bar' => 2) s = hash.subhash('foo') assert_equal 1, s['foo'] assert_equal :foo, s['bar'] end end end tins-1.32.1/tests/implement_test.rb0000644000004100000410000000315714353307475017344 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class ImplementTest < Test::Unit::TestCase require 'tins/xt/implement' class A implement :foo implement :bar, in: :subclass implement :baz, in: :submodule implement :qux, 'blub %{method_name} blob %{module}' implement :quux, 'blab' implement def foobar(arg1, arg2: :baz) end, in: :subclass end def test_implement_default assert_equal( 'method foo not implemented in module Tins::ImplementTest::A', error_message { A.new.foo } ) end def test_implement_subclass assert_equal( 'method bar has to be implemented in subclasses of '\ 'Tins::ImplementTest::A', error_message { A.new.bar } ) end def test_implement_submodule assert_equal( 'method baz has to be implemented in submodules of '\ 'Tins::ImplementTest::A', error_message { A.new.baz } ) end def test_implement_custom_with_vars assert_equal( 'blub qux blob Tins::ImplementTest::A', error_message { A.new.qux } ) end def test_implement_custom_without_vars assert_equal('blab', error_message { A.new.quux }) end if RUBY_VERSION >= "2.1" def test_implement_def_subclass assert_equal( 'method foobar(arg1,arg2:?) has to be '\ 'implemented in subclasses of Tins::ImplementTest::A', error_message { A.new.foobar } ) end end private def error_message yield rescue NotImplementedError => e e.message end end end tins-1.32.1/tests/find_test.rb0000644000004100000410000001113114353307475016261 0ustar www-datawww-datarequire 'test_helper' require 'tins/find' require 'fileutils' require 'tempfile' module Tins class FindTest < Test::Unit::TestCase include Tins::Find include FileUtils def setup mkdir_p @work_dir = File.join(Dir.tmpdir, "test.#$$") end def teardown rm_rf @work_dir end def test_raising_errors assert_equal [], find(File.join(@work_dir, 'nix'), raise_errors: false).to_a assert_equal [], find(File.join(@work_dir, 'nix')).to_a assert_raise(Errno::ENOENT) do find(File.join(@work_dir, 'nix'), raise_errors: true).to_a end end def test_showing_hidden touch file = File.join(@work_dir, '.foo') assert_equal [ @work_dir ], find(@work_dir, show_hidden: false).to_a assert_equal [ @work_dir, file ], find(@work_dir).to_a assert_equal [ @work_dir, file ], find(@work_dir, show_hidden: true).to_a end def test_check_directory_without_access # do not run this test on JRuby omit_if(RUBY_PLATFORM =~ /java/, "Can't run the test on JRuby") # do not run this test if we're root, as it will fail. omit_if(Process::UID.eid == 0, "Can't run the test as root") begin mkdir_p directory1 = File.join(@work_dir, 'foo') mkdir_p directory2 = File.join(directory1, 'bar') touch File.join(directory2, 'file') chmod 0, directory2 assert_equal [ @work_dir, directory1, directory2 ], find(@work_dir, raise_errors: false).to_a assert_equal [ @work_dir, directory1, directory2 ], find(@work_dir).to_a assert_raise(Errno::EACCES) do find(@work_dir, raise_errors: true).to_a end ensure File.exist?(directory2) and chmod 0777, directory2 end end def test_follow_symlinks mkdir_p directory1 = File.join(@work_dir, 'foo1') mkdir_p directory2 = File.join(@work_dir, 'foo2') mkdir_p directory3 = File.join(directory1, 'bar') touch File.join(directory3, 'foo') ln_s directory3, link = File.join(directory2, 'baz') assert_equal [ directory2, link ], find(directory2, follow_symlinks: false).to_a assert_equal [ directory2, link, linked = File.join(link, 'foo') ], find(directory2).to_a assert_equal [ directory2, link, linked ], find(directory2, follow_symlinks: true).to_a end def test_path_file File.open(File.join(@work_dir, 'foo'), 'w') do |f| f.print "hello" f.fsync assert_equal "hello", find(@work_dir). select { |fs| fs.stat.file? }.first.file.read end end def test_path_extension finder = Tins::Find::Finder.new f = File.open(path = File.join(@work_dir, 'foo.bar'), 'w') ln_s path, path2 = File.join(@work_dir, 'foo2.bar') path2 = finder.prepare_path path2 path = finder.prepare_path path assert_true path.exist? assert_true path.file? assert_false path.directory? assert_true finder.prepare_path(Dir.pwd).directory? assert_equal Pathname.new(path), path.pathname assert_equal 'bar', path.suffix assert_true path2.lstat.symlink? ensure f and rm_f f.path end def test_suffix finder = Tins::Find::Finder.new(suffix: 'bar') f = File.open(fpath = File.join(@work_dir, 'foo.bar'), 'w') g = File.open(gpath = File.join(@work_dir, 'foo.baz'), 'w') fpath = finder.prepare_path fpath gpath = finder.prepare_path gpath assert_true finder.visit_path?(fpath) assert_false finder.visit_path?(gpath) finder.suffix = nil assert_true finder.visit_path?(fpath) assert_true finder.visit_path?(gpath) ensure f and rm_f f.path g and rm_f g.path end def test_visit assert_raise(ArgumentError) do Tins::Find::Finder.new(visit: :foo, suffix: 'bla') end finder = Tins::Find::Finder.new(visit: -> path { path.stat.file? }) File.new(fpath = File.join(@work_dir, 'foo.bar'), 'w').close mkdir_p(gpath = File.join(@work_dir, 'dir')) fpath = finder.prepare_path fpath gpath = finder.prepare_path gpath assert_true finder.visit_path?(fpath) assert_false finder.visit_path?(gpath) found = [] Tins::Find.find( @work_dir, visit: -> path { path.stat.directory? or prune } ) { |f| found << f } assert_equal [ @work_dir, gpath ], found end def test_prune mkdir_p directory1 = File.join(@work_dir, 'foo1') mkdir_p File.join(@work_dir, 'foo2') result = [] find(@work_dir) { |f| f =~ /foo2\z/ and prune; result << f } assert_equal [ @work_dir, directory1 ], result end end end tins-1.32.1/tests/proc_prelude_test.rb0000644000004100000410000000324514353307475020033 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt/proc_prelude' module Tins class ProcPreludeTest < Test::Unit::TestCase def test_apply assert_equal 42, Proc.apply { |x, y, z| x ** 2 + y ** 3 + z ** 5 }.call([3, 1, 2]) end class Person def initialize(name) @name = name end attr_reader :name end def test_map_apply ps = %w[anne bernd christian].map { |n| Person.new(n) } i = 0 assert_equal %w[ anne1 bernd2 christian3 ], ps.inject([], &Proc.map_apply(:name) { |s, n| s << "#{n}#{i += 1}" }) end def test_call def (o = Object.new).foo :foo end assert_equal :foo, Proc.call(o) { foo } end def test_array assert_equal [1,2,3], Proc.array.call(1,2,3) end def test_first assert_equal 1, Proc.first.call(1,2,3) assert_equal 1, Proc.head.call(1,2,3) end def test_second assert_equal 2, Proc.second.call(1,2,3) end def test_tail assert_equal [ 2, 3 ], Proc.tail.call(1,2,3) end def test_last assert_equal 3, Proc.last.call(1,2,3) end def test_rotate assert_equal [ 2, 3, 1 ], Proc.rotate.call(1,2,3) assert_equal [ 2, 1 ], Proc.swap.call(1,2) end def test_id1 assert_equal :foo, Proc.id1.call(:foo) end def test_const assert_equal :baz, Proc.const(:baz).call(:foo, :bar) assert_equal :baz, Proc.const { :baz }.call(:foo, :bar) end def test_nth assert_equal 2, Proc.nth(1).call(1,2,3) end def square(x) x ** 2 end def test_from assert_equal [ 1, 4, 9 ], [ 1, 2, 3 ].map(&Proc.from{:square}) end end end tins-1.32.1/tests/scope_test.rb0000644000004100000410000000135314353307475016457 0ustar www-datawww-datarequire 'test_helper' require 'tins' class ScopeTest < Test::Unit::TestCase include Tins::Scope def test_default_scope scope_block(:foo) do assert_equal [ :foo ], scope scope_block(:bar) do assert_equal [ :foo, :bar ], scope scope.push :baz assert_equal [ :foo, :bar ], scope end end end def test_two_scopes scope_block(:foo, :my_scope) do assert_equal [ :foo ], scope(:my_scope) scope_block(:baz) do scope_block(:bar, :my_scope) do assert_equal [ :foo, :bar ], scope(:my_scope) scope.push(:baz, :my_scope) assert_equal [ :foo, :bar ], scope(:my_scope) assert_equal [ :baz ], scope end end end end end tins-1.32.1/tests/rotate_test.rb0000644000004100000410000000240614353307475016644 0ustar www-datawww-datarequire 'test_helper' module Tins class RotateTest < Test::Unit::TestCase def test_rotate_bang a = [ 1, 2, 3 ] assert_same a, a.rotate! end def test_rotate_bang_0 a = [ 1, 2, 3 ] assert_equal [ 1, 2, 3 ], a.rotate!(0) end def test_rotate_bang_1 a = [ 1, 2, 3 ] assert_equal [ 2, 3, 1 ], a.rotate!(1) end def test_rotate_bang_2 a = [ 1, 2, 3 ] assert_equal [ 3, 1, 2 ], a.rotate!(2) end def test_rotate_bang_minus_1 a = [ 1, 2, 3 ] assert_equal [ 3, 1, 2 ], a.rotate!(-1) end def test_rotate_bang_minus_2 a = [ 1, 2, 3 ] assert_equal [ 2, 3, 1 ], a.rotate!(-2) end def test_rotate a = [ 1, 2, 3 ] assert_not_same a, a.rotate end def test_rotate_0 a = [ 1, 2, 3 ] assert_equal [ 1, 2, 3 ], a.rotate(0) end def test_rotate_1 a = [ 1, 2, 3 ] assert_equal [ 2, 3, 1 ], a.rotate(1) end def test_rotate_2 a = [ 1, 2, 3 ] assert_equal [ 3, 1, 2 ], a.rotate(2) end def test_rotate_minus_1 a = [ 1, 2, 3 ] assert_equal [ 3, 1, 2 ], a.rotate(-1) end def test_rotate_minus_2 a = [ 1, 2, 3 ] assert_equal [ 2, 3, 1 ], a.rotate(-2) end end end tins-1.32.1/tests/ask_and_send_test.rb0000644000004100000410000000200214353307475017747 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class AskAndSendTest < Test::Unit::TestCase class A public def foo :foo end private def bar :bar end end def test_asking_publicly assert_equal :foo, A.new.ask_and_send(:foo) assert_nil A.new.ask_and_send(:bar) assert_nil A.new.ask_and_send(:baz) end def test_asking_privately assert_equal :foo, A.new.ask_and_send!(:foo) assert_equal :bar, A.new.ask_and_send!(:bar) assert_nil A.new.ask_and_send(:baz) end def test_asking_selfy_publicly a = A.new assert_equal :foo, a.ask_and_send_or_self(:foo) assert_equal a, a.ask_and_send_or_self(:bar) assert_equal a, a.ask_and_send_or_self(:baz) end def test_asking_selfy_privately a = A.new assert_equal :foo, a.ask_and_send_or_self!(:foo) assert_equal :bar, a.ask_and_send_or_self!(:bar) assert_equal a, a.ask_and_send_or_self(:baz) end end end tins-1.32.1/tests/expose_test.rb0000644000004100000410000000155414353307475016654 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt/expose' module Tins class ExposeTest < Test::Unit::TestCase class A def priv :priv end private :priv def prot(x) :prot end protected :prot end def setup @a = A.new end def test_raises_exception_unless_exposed assert_raise(NoMethodError) { @a.priv } assert_raise(NoMethodError) { @a.prot(:any) } end def test_exposes_all_methods @a = @a.expose assert_equal :priv, @a.priv assert_equal :prot, @a.prot(:any) end def test_exposes_all_methods_in_block assert_equal :priv, @a.expose { priv } assert_equal :prot, @a.expose { prot(:any) } end def test_exposes_specified_method_call assert_equal :priv, @a.expose(:priv) assert_equal :prot, @a.expose(:prot, :any) end end end tins-1.32.1/tests/hash_symbolize_keys_recursive_test.rb0000644000004100000410000000340214353307475023505 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class HashSymbolizeKeysRecursiveTest < Test::Unit::TestCase require 'tins/xt/hash_symbolize_keys_recursive' def test_symbolize hash = { 'key' => [ { 'key' => { 'key' => true }, 'o' => Object.new, } ], } hash2 = hash.symbolize_keys_recursive assert hash2[:key][0][:key][:key] hash.symbolize_keys_recursive! assert hash[:key][0][:key][:key] end def test_symbolize_bang hash = { 'foo' => 'bar' } hash.symbolize_keys_recursive! assert_equal({ foo: 'bar' }, hash) end def test_symbolize_with_circular_array circular_array = [].tap { |a| a << a } assert_equal( { foo: [ nil ] }, { 'foo' => circular_array }.symbolize_keys_recursive ) assert_equal( { foo: [ :circular ] }, { 'foo' => circular_array }.symbolize_keys_recursive(circular: :circular) ) end def test_symbolize_with_circular_hash circular_hash = {}.tap { |h| h['foo'] = h } circular_hash_symbol = {}.tap { |h| h[:foo] = nil } assert_equal( { bar: circular_hash_symbol }, { 'bar' => circular_hash }.symbolize_keys_recursive ) assert_equal( { bar: { foo: :circular } }, { 'bar' => circular_hash }.symbolize_keys_recursive(circular: :circular) ) end def test_symbolize_deeper_nesting hash = { 'foo' => [ true, [ { 'bar' => {}.tap { |h| h['foo'] = h } }, 3.141, [].tap { |arr| arr << arr } ] ] } assert_equal( {foo: [true, [{bar: {foo: :circular}}, 3.141, [:circular]]]}, hash.symbolize_keys_recursive(circular: :circular) ) end end end tins-1.32.1/tests/annotate_test.rb0000644000004100000410000000304314353307475017155 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class AnnotateTest < Test::Unit::TestCase require 'tins/xt/annotate' class A annotate :foo annotate :bar foo 'test foo1' bar 'test bar1' def first end foo 'test foo2' bar 'test bar2' def second end bar 'test bar3' def third end foo def fourth end end def test_annotations_via_class assert_equal 'test foo1', A.foo_of(:first) assert_equal 'test bar1', A.bar_of(:first) assert_equal 'test foo2', A.foo_of(:second) assert_equal 'test bar2', A.bar_of(:second) assert_equal nil, A.foo_of(:third) assert_equal 'test bar3', A.bar_of(:third) end def test_annotations_via_instance a = A.new assert_equal 'test foo1', a.foo_of(:first) assert_equal 'test bar1', a.bar_of(:first) assert_equal 'test foo2', a.foo_of(:second) assert_equal 'test bar2', a.bar_of(:second) assert_equal nil, a.foo_of(:third) assert_equal 'test bar3', a.bar_of(:third) end def test_annotations_without_args assert_equal :annotated, A.foo_of(:fourth) a = A.new assert_equal :annotated, a.foo_of(:fourth) end def test_query_methods assert_equal( { :first=>"test foo1", :fourth=>:annotated, :second=>"test foo2" }, A.foo_annotations ) assert_equal( { :first=>"test foo1", :fourth=>:annotated, :second=>"test foo2" }, A.new.foo_annotations ) end end end tins-1.32.1/tests/date_time_dummy_test.rb0000644000004100000410000000155614353307475020521 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class DateTimeDummyTest < Test::Unit::TestCase require 'tins/xt/date_time_dummy' require 'date' def test_time_dummy date_time = DateTime.parse('2009-09-09 21:09:09') assert_not_equal date_time, DateTime.now DateTime.dummy = date_time assert_equal date_time, DateTime.now DateTime.dummy = nil assert_not_equal date_time, DateTime.now end def test_time_dummy_block date_time = DateTime.parse('2009-09-09 21:09:09') assert_not_equal date_time, DateTime.now DateTime.dummy date_time do assert_equal date_time, DateTime.now DateTime.dummy date_time + 1 do assert_equal date_time + 1, DateTime.now end assert_equal date_time, DateTime.now end assert_not_equal date_time, DateTime.now end end end tins-1.32.1/tests/partial_application_test.rb0000644000004100000410000000131314353307475021361 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class PartialApplicationTest < Test::Unit::TestCase def mul(x, y) x * y end define_method(:dup) { |y| method(:mul).partial(2)[y] } define_method(:trip) { |y| method(:mul).partial(3)[y] } def test_proc mul = lambda { |x, y| x * y } klon = mul.partial dup = mul.partial(2) trip = mul.partial(3) assert_equal [ 6, 9, 12 ], [ dup[3], trip[3], mul[4, 3] ] assert_equal [ 6, 9, 12 ], [ dup[3], trip[3], klon[4, 3] ] assert_raise(ArgumentError) do mul.partial(1, 2, 3) end end def test_method assert_equal [ 6, 9, 12 ], [ dup(3), trip(3), mul(4, 3) ] end end end tins-1.32.1/tests/to_test.rb0000644000004100000410000000124114353307475015764 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt/to' module Tins class ToTest < Test::Unit::TestCase def test_to_removing_leading_spaces doc = to(<<-end) hello, world end assert_equal "hello, world\n", doc end def test_to_removing_leading_spaces_depending_on_first_line doc = to(<<-end) hello world, how are things? end assert_equal "hello\n world,\n how are\n things?\n", doc end def test_to_not_removing_empty_lines doc = to(<<-end) hello, world another line end assert_equal "hello, world\n\nanother line\n", doc end end end tins-1.32.1/tests/memoize_test.rb0000644000004100000410000000706514353307475017021 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class MemoizeTest < Test::Unit::TestCase class FooBar def foo(*a) @@foo ||= 0 @@foo += 1 end memoize_method :foo def footsie(*a) @@footsie ||= 0 @@footsie += 1 end protected :footsie memoize_method :footsie def bar(*a) @@bar ||= 0 @@bar += 1 end memoize_function :bar private def baz(*a) @@baz ||= 0 @@baz += 1 end memoize_function :baz end def test_method_cache fb1 = FooBar.new fb2 = FooBar.new assert_equal true, fb1.__memoize_cache__.empty? assert_equal true, fb2.__memoize_cache__.empty? assert_equal 1, fb1.foo(1, 2) assert_equal 2, fb2.foo(1, 2) assert_equal 3, fb1.foo(1, 2, 3) assert_equal 4, fb2.foo(1, 2, 3) assert_equal 1, fb1.foo(1, 2) assert_equal 2, fb2.foo(1, 2) fb1.memoize_cache_clear fb2.memoize_cache_clear assert_equal true, fb1.__memoize_cache__.empty? assert_equal true, fb2.__memoize_cache__.empty? assert_equal 5, fb1.foo(1, 2) assert_equal 6, fb2.foo(1, 2) assert_equal 5, fb1.foo(1, 2) assert_equal 6, fb2.foo(1, 2) assert_equal false, fb1.__memoize_cache__.empty? assert_equal false, fb2.__memoize_cache__.empty? end def test_method_cache_protected fb1 = FooBar.new fb2 = FooBar.new assert_raise(NoMethodError) { fb1.footsie(1, 2) } assert_raise(NoMethodError) { fb2.footsie(1, 2) } assert_equal true, fb1.__memoize_cache__.empty? assert_equal true, fb2.__memoize_cache__.empty? assert_equal 1, fb1.__send__(:footsie, 1, 2) assert_equal 2, fb2.__send__(:footsie, 1, 2) assert_equal 3, fb1.__send__(:footsie, 1, 2, 3) assert_equal 4, fb2.__send__(:footsie, 1, 2, 3) assert_equal 1, fb1.__send__(:footsie, 1, 2) assert_equal 2, fb2.__send__(:footsie, 1, 2) fb1.memoize_cache_clear fb2.memoize_cache_clear assert_equal true, fb1.__memoize_cache__.empty? assert_equal true, fb2.__memoize_cache__.empty? assert_equal 5, fb1.__send__(:footsie, 1, 2) assert_equal 6, fb2.__send__(:footsie, 1, 2) assert_equal 5, fb1.__send__(:footsie, 1, 2) assert_equal 6, fb2.__send__(:footsie, 1, 2) assert_equal false, fb1.__memoize_cache__.empty? assert_equal false, fb2.__memoize_cache__.empty? end def test_function_cache fb1 = FooBar.new fb2 = FooBar.new assert_equal 1, fb1.bar(1, 2) assert_equal 1, fb2.bar(1, 2) assert_equal 2, fb1.bar(1, 2, 3) assert_equal 2, fb2.bar(1, 2, 3) assert_equal 1, fb1.bar(1, 2) assert_equal 1, fb2.bar(1, 2) FooBar.memoize_cache_clear assert_equal 3, fb1.bar(1, 2) assert_equal 3, fb2.bar(1, 2) assert_equal false, FooBar.__memoize_cache__.empty? end def test_function_cache_private fb1 = FooBar.new fb2 = FooBar.new assert_raise(NoMethodError) { fb1.baz(1, 2) } assert_raise(NoMethodError) { fb2.baz(1, 2) } assert_equal 1, fb1.__send__(:baz, 1, 2) assert_equal 1, fb2.__send__(:baz, 1, 2) assert_equal 2, fb1.__send__(:baz, 1, 2, 3) assert_equal 2, fb2.__send__(:baz, 1, 2, 3) assert_equal 1, fb1.__send__(:baz, 1, 2) assert_equal 1, fb2.__send__(:baz, 1, 2) FooBar.memoize_cache_clear assert_equal 3, fb1.__send__(:baz, 1, 2) assert_equal 3, fb2.__send__(:baz, 1, 2) assert_equal false, FooBar.__memoize_cache__.empty? end end end tins-1.32.1/tests/p_test.rb0000644000004100000410000000037514353307475015610 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt/p' module Tins class PTest < Test::Unit::TestCase def test_p_bang assert_raise(RuntimeError) { p! "foo" } end def test_pp_bang assert_raise(RuntimeError) { pp! "foo" } end end end tins-1.32.1/tests/date_dummy_test.rb0000644000004100000410000000135214353307475017475 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class DateDummyTest < Test::Unit::TestCase require 'tins/xt/date_dummy' require 'date' def test_date_dummy date = Date.parse('2009-09-09') assert_not_equal date, Date.today Date.dummy = date assert_equal date, Date.today Date.dummy = nil assert_not_equal date, Date.today end def test_date_dummy_block date = Date.parse('2009-09-09') assert_not_equal date, Date.today Date.dummy date do assert_equal date, Date.today Date.dummy date + 1 do assert_equal date + 1, Date.today end assert_equal date, Date.today end assert_not_equal date, Date.today end end end tins-1.32.1/tests/case_predicate_test.rb0000644000004100000410000000126314353307475020301 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt/case_predicate' module Tins class CasePredicateTest < Test::Unit::TestCase def test_case_predicate_failure assert_nil 4.case?(1, 2..3, 5...7) end def test_case_predicate_failure_is_a s = 'foo' assert_nil s.case?(Array, Hash) s = Class.new(String).new assert_nil s.case?(Array, Hash) end def test_case_predicate_success assert_equal 2..3, 3.case?(1, 2..3, 5...7) end def test_case_predicate_success_is_a s = 'foo' assert_equal String, s.case?(Array, Hash, String) s = Class.new(String).new assert_equal String, s.case?(Array, Hash, String) end end end tins-1.32.1/tests/dynamic_scope_test.rb0000644000004100000410000000144714353307475020167 0ustar www-datawww-datarequire 'test_helper' require 'tins' class DynamicScopeTest < Test::Unit::TestCase include Tins::DynamicScope def test_dynamic_scoping assert_raise(NameError) { foo } assert_equal false, dynamic_defined?(:foo) dynamic_scope do assert_raise(NameError) { foo } assert_equal false, dynamic_defined?(:foo) self.foo = 1 assert_equal 1, foo assert_equal true, dynamic_defined?(:foo) dynamic_scope do assert_equal 1, foo assert_equal true, dynamic_defined?(:foo) self.foo = 2 assert_equal 2, foo dynamic_scope do assert_equal 2, foo end assert_equal 2, foo end assert_equal 1, foo end assert_equal false, dynamic_defined?(:foo) assert_raise(NameError) { foo } end end tins-1.32.1/tests/lru_cache_test.rb0000644000004100000410000000207714353307475017277 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class LRUCacheTest < Test::Unit::TestCase def setup @cache = LRUCache.new(3) end def test_can_be_filled_to_capacity assert_equal 0, @cache.size @cache[1] = 1 assert_equal 1, @cache.size @cache[2] = 2 assert_equal 2, @cache.size @cache[3] = 3 assert_equal 3, @cache.size @cache[4] = 4 assert_equal 3, @cache.size assert_equal 4, @cache.first[0] end def test_reorders_based_on_recency (1..3).each do |i| @cache[i] = i end assert_equal 3, @cache.first[0] @cache[1] assert_equal 1, @cache.first[0] end def test_can_be_cleared (1..3).each do |i| @cache[i] = i end assert_equal 3, @cache.size @cache.clear assert_equal 0, @cache.size end def test_can_be_deleted_from (1..3).each do |i| @cache[i] = i end assert_equal 3, @cache.size @cache.delete 2 assert_equal 2, @cache.size assert_nil @cache[2] end end end tins-1.32.1/tests/deep_const_get_test.rb0000644000004100000410000000202414353307475020324 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt/deep_const_get' module Tins class DeepConstGetTest < Test::Unit::TestCase module A module B end end module C module NotB end def self.const_missing(c) NotB end end def test_deep_const_get_with_start_module assert_raise(ArgumentError) { deep_const_get '::B', A } assert_equal A::B, deep_const_get('B', A) end def test_deep_const_get_without_start_module assert_equal Tins::DeepConstGetTest::A::B, deep_const_get('::Tins::DeepConstGetTest::A::B') assert_equal Tins::DeepConstGetTest::A::B, deep_const_get('Tins::DeepConstGetTest::A::B') assert_equal Array, deep_const_get('::Array') assert_equal Array, deep_const_get('Array') end def test_deep_const_get_with_const_missing assert_raise(ArgumentError) { deep_const_get '::Tins::DeepConstGetTest::A::NIXDA' } assert_equal Tins::DeepConstGetTest::C::NotB, deep_const_get('::Tins::DeepConstGetTest::C::B') end end end tins-1.32.1/tests/string_camelize_test.rb0000644000004100000410000000142714353307475020527 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class StringCamelizeTest < Test::Unit::TestCase def test_camelize assert_equal 'FooBar', 'foo_bar'.camelize assert_equal 'FooBar', 'foo_bar'.camelize(:upper) assert_equal 'FooBar', 'foo_bar'.camelize(true) assert_equal 'fooBar', 'foo_bar'.camelize(:lower) assert_equal 'fooBar', 'foo_bar'.camelize(false) assert_equal 'FooBar', 'foo_bar'.camelcase assert_equal 'Foo::Bar', 'foo/bar'.camelize assert_equal 'Foo::Bar', 'foo/bar'.camelize(:upper) assert_equal 'Foo::Bar', 'foo/bar'.camelize(true) assert_equal 'foo::Bar', 'foo/bar'.camelize(:lower) assert_equal 'foo::Bar', 'foo/bar'.camelize(false) assert_equal 'Foo::Bar', 'foo/bar'.camelcase end end end tins-1.32.1/tests/time_freezer_test.rb0000644000004100000410000000273214353307475020030 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class TimeFreezerTest < Test::Unit::TestCase def test_freezing freezing_point = '2011-11-11T11:11:11Z' Tins::TimeFreezer.freeze(freezing_point) do assert_equal "2011-11-11 11:11:11 UTC", Time.now.to_s assert_equal "2011-11-11T11:11:11+00:00", DateTime.now.to_s assert_equal "2011-11-11", Date.today.to_s end end def test_to_time_conversion freezing_point = '2011-11-11T11:11:11Z' time = Time.parse(freezing_point) Tins::TimeFreezer.freeze(time) do assert_equal "2011-11-11 11:11:11 UTC", Time.now.utc.to_s assert_equal "2011-11-11T11:11:11+00:00", DateTime.now.to_s assert_equal "2011-11-11", Date.today.to_s end end def test_to_date_conversion freezing_point = '2011-11-11Z' date = Date.parse(freezing_point) Tins::TimeFreezer.freeze(date) do assert_equal "2011-11", Time.now.utc.to_s[0, 7] assert_equal "2011-11", DateTime.now.to_s[0, 7] assert_equal "2011-11", Date.today.to_s[0, 7] end end def test_to_datetime_conversion freezing_point = '2011-11-11T11:11:11Z' datetime = DateTime.parse(freezing_point) Tins::TimeFreezer.freeze(datetime) do assert_equal "2011-11-11 11:11:11 UTC", Time.now.utc.to_s assert_equal "2011-11-11T11:11:11+00:00", DateTime.now.to_s assert_equal "2011-11-11", Date.today.to_s end end end end tins-1.32.1/tests/responding_test.rb0000644000004100000410000000116214353307475017514 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class RespondingTest < Test::Unit::TestCase class A def foo() end def bar() end end def test_responding assert_equal true, responding?(:foo) === A.new assert_equal false, responding?(:jflafjdklfjaslkdfj) === A.new assert_equal false, responding?(:jflafjdklfjaslkdfj, :foo) === A.new assert_equal true, responding?(:foo, :bar) === A.new end def test_responding_to_s assert_equal 'Responding to foo', responding?(:foo).to_s assert_equal 'Responding to foo', responding?(:foo).inspect end end end tins-1.32.1/tests/extract_last_argument_options_test.rb0000644000004100000410000000162014353307475023515 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class ExtractLastArgumentOptionsTest < Test::Unit::TestCase require 'tins/xt/extract_last_argument_options' def test_empty_argument_array arguments = [] result = arguments.extract_last_argument_options assert_equal [ [], {} ], result assert_not_same arguments, result.first end def test_argument_array_without_options arguments = [ 1, 2, 3 ] result = arguments.extract_last_argument_options assert_equal [ [ 1, 2, 3 ], {} ], result assert_not_same arguments, result.first end def test_argument_array_witt_options arguments = [ 1, 2, 3, { foo: :bar } ] result = arguments.extract_last_argument_options assert_equal [ [ 1, 2, 3 ], { foo: :bar } ], result assert_not_same arguments, result.first assert_not_same arguments.last, result.last end end end tins-1.32.1/tests/proc_compose_test.rb0000644000004100000410000000077314353307475020043 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class ProcComposeTest < Test::Unit::TestCase def test_proc_compose_simple f = lambda { |x| 2 * x } g = lambda { |x| x + 1 } assert_equal 6, (f * g).call(2) end def test_proc_compose_more_complex f = lambda { |x, y| 2 * x + y * 3 } g = lambda { |x| x + 1 } assert_raise(ArgumentError) { (f * g).call(2, 3) } d = lambda { |x| [ x, x ] } assert_equal 15, (f * d * g).call(2) end end end tins-1.32.1/tests/count_by_test.rb0000644000004100000410000000105414353307475017166 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class CountByTest < Test::Unit::TestCase def test_count_by assert_equal 0, [].count_by { |x| x % 2 == 0 } assert_equal 0, [ 1 ].count_by { |x| x % 2 == 0 } assert_equal 1, [ 1 ].count_by { |x| x % 2 == 1 } assert_equal 1, [ 1, 2 ].count_by { |x| x % 2 == 0 } assert_equal 1, [ 1, 2 ].count_by { |x| x % 2 == 1 } assert_equal 2, [ 1, 2, 3, 4, 5 ].count_by { |x| x % 2 == 0 } assert_equal 3, [ 1, 2, 3, 4, 5 ].count_by { |x| x % 2 == 1 } end end end tins-1.32.1/tests/uniq_by_test.rb0000644000004100000410000000142714353307475017016 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class UniqByTest < Test::Unit::TestCase unless defined?(Point) class Point < Struct.new :x, :y end end def test_uniq_by assert_equal [ 1, 2, 3 ], [ 1, 2, 2, 3 ].uniq_by.sort a = [ 1, 2, 2, 3 ]; a.uniq_by! assert_equal [ 1, 2, 3 ], a.sort p1 = Point.new 1, 2 p2 = Point.new 2, 2 p3 = Point.new 2, 2 p4 = Point.new 3, 3 a = [ p1, p2, p3, p4 ] a_uniq = a.uniq_by { |p| p.y } assert_equal 2, a_uniq.size assert a_uniq.include?(p4) assert [ p1, p2, p3 ].any? { |p| a_uniq.include? p } a.uniq_by! { |p| p.y } assert_equal 2, a.size assert a.include?(p4) assert [ p1, p2, p3 ].any? { |p| a.include? p } end end end tins-1.32.1/tests/token_test.rb0000644000004100000410000000213114353307475016461 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class TokenTest < Test::Unit::TestCase def test_token_failures assert_raise(ArgumentError) { Tins::Token.new(bits: 0) } assert_raise(ArgumentError) { Tins::Token.new(length: 0) } assert_raise(ArgumentError) { Tins::Token.new(alphabet: %w[0]) } end def test_token_for_length token = Tins::Token.new(length: 22) assert_equal 22, token.length assert_equal 130, token.bits end def test_token_for_bits token = Tins::Token.new(bits: 128) assert_equal 22, token.length # can differ from bits argument depending on alphabet: assert_equal 130, token.bits end def test_alphabet token = Tins::Token.new(alphabet: %w[0 1]) assert_equal 128, token.length assert_equal 128, token.bits token = Tins::Token.new(alphabet: %w[0 1 2 3]) assert_equal 64, token.length assert_equal 128, token.bits token = Tins::Token.new(length: 128, alphabet: %w[0 1 2 3]) assert_equal 128, token.length assert_equal 256, token.bits end end end tins-1.32.1/tests/from_module_test.rb0000644000004100000410000000167214353307475017662 0ustar www-datawww-datarequire 'test_helper' require 'tins' class FromModuleTest < Test::Unit::TestCase module MyIncludedModule def foo :foo end def bar :bar end end class MyKlass def foo :original_foo end def bar :original_bar end end class DerivedKlass < MyKlass extend Tins::FromModule include from module: MyIncludedModule, methods: [ :foo ] end module MyModule def foo :original_foo end def bar :original_bar end include MyIncludedModule end class AnotherDerivedKlass include MyModule extend Tins::FromModule include from module: MyIncludedModule, methods: :foo end def test_derived_klass c = DerivedKlass.new assert_equal :foo, c.foo assert_equal :original_bar, c.bar end def test_another_derived_klass c = AnotherDerivedKlass.new assert_equal :foo, c.foo assert_equal :original_bar, c.bar end end tins-1.32.1/tests/module_group_test.rb0000644000004100000410000000107314353307475020046 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class ModuleGroupTest < Test::Unit::TestCase MyClasses = Tins::ModuleGroup[ Array, String, Hash ] def test_module_group assert MyClasses === [] assert MyClasses === "" assert MyClasses === {} assert !(MyClasses === :nix) case [] when MyClasses assert true when Array assert false end case :nix when MyClasses assert false when Array assert false when Symbol assert true end end end end tins-1.32.1/tests/delegate_test.rb0000644000004100000410000000146114353307475017120 0ustar www-datawww-datarequire 'test_helper' require 'tins' class DelegationTestClass class DelegationTestClass2 def self.size 5 end end extend Tins::Delegate def self.size 1 end @@ary = [ 1, 2 ] def initialize @ary = [ 1, 2, 3 ] end def ary [ 1, 2, 3, 4 ] end delegate :size, to: :class delegate :size, to: :@@ary, as: 'cvar_size' delegate :size, to: :@ary, as: 'ivar_size' delegate :size, to: :ary, as: 'method_size' delegate :size, to: 'DelegationTestClass::DelegationTestClass2', as: 'class_size' end class DelegateTest < Test::Unit::TestCase def test_delegate d = DelegationTestClass.new assert_equal 1, d.size assert_equal 2, d.cvar_size assert_equal 3, d.ivar_size assert_equal 4, d.method_size assert_equal 5, d.class_size end end tins-1.32.1/tests/attempt_test.rb0000644000004100000410000001114614353307475017025 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class AttemptTest < Test::Unit::TestCase class MyError < StandardError; end class MyException < Exception; end def test_attempt_with_invalid_arguments assert_raise(ArgumentError) { attempt(attempts: 0) { } } end def test_attempt_block_condition assert attempt(attempts: 1, exception_class: nil) { |c| c == 1 } assert attempt(attempts: 3, exception_class: nil) { |c| c == 1 } assert_equal false, attempt(attempts: 3, exception_class: nil) { |c| c == 4 } assert_raise(MyException) { attempt(attempts: 3, exception_class: nil) { raise MyException } } end def test_attempt_default_exception assert attempt(1) { |c| c != 1 and raise MyError } assert attempt(3) { |c| c != 1 and raise MyError } assert_equal false, attempt(3) { |c| c != 4 and raise MyError } assert_raise(Exception) { attempt(3) { raise Exception } } end def test_attempt_exception assert_equal false, attempt(attempts: 3, exception_class: MyException) { raise MyException } assert_equal true, attempt(attempts: 3, exception_class: MyException) { |c| c == 1 and raise MyException } end def test_reraise_exception_true tries = 0 assert_raise(MyException) do attempt(attempts: 3, exception_class: MyException, reraise: true) do |c| tries = c; raise MyException end end assert_equal 3, tries end def test_reraise_exception_exception_class other_exception = Exception tries = 0 assert_raise(other_exception) do attempt(attempts: 3, exception_class: MyException, reraise: other_exception) do |c| tries = c; raise MyException end end assert_equal 3, tries end def test_reraise_exception_proc other_exception = Exception tries = 0 assert_raise(other_exception, 'hi ho') do attempt(attempts: 3, exception_class: MyException, reraise: -> e { raise other_exception, 'hi ho' }) do |c| tries = c; raise MyException end end assert_equal 3, tries end def test_reraise_exception_with_positive_sleep tries = 0 singleton_class.class_eval do define_method(:sleep_duration) do |duration, count| assert_equal 10, duration tries = count super 0, count # Let's not really sleep that long… end end assert_raise(MyException) do attempt(attempts: 3, exception_class: MyException, reraise: true, sleep: 10) do |c| raise MyException end end assert_equal 2, tries ensure singleton_class.class_eval do method_defined?(:sleep_duration) and remove_method :sleep_duration end end def test_reraise_exception_with_proc_sleep tries = 0 singleton_class.class_eval do define_method(:sleep_duration) do |duration, count| assert_kind_of Proc, duration tries = count super duration, count end end assert_raise(MyException) do attempt(attempts: 3, exception_class: MyException, reraise: true, sleep: -> x { 0 }) do |c| raise MyException end end assert_equal 2, tries ensure singleton_class.class_eval do method_defined?(:sleep_duration) and remove_method :sleep_duration end end def test_reraise_exception_with_negative_sleep tries = 0 sleeps = [ 2.701, 7.298 ] singleton_class.class_eval do define_method(:sleep_duration) do |duration, count| assert_in_delta sleeps[tries], duration.call(count), 1E-3 tries = count super 0, count # Let's not really sleep that long… end end assert_raise(MyException) do attempt(attempts: 3, exception_class: MyException, reraise: true, sleep: -10) do |c| raise MyException end end assert_equal 2, tries ensure singleton_class.class_eval do method_defined?(:sleep_duration) and remove_method :sleep_duration end end def test_attempt_previous_exception_block_arg last_e = nil attempt(1) { |c, prev_e| last_e = prev_e } assert_nil last_e attempt(2) { |c, prev_e| last_e = prev_e; c == 1 and raise MyError } assert_kind_of MyError, last_e attempt(3) { |c, prev_e| last_e = prev_e; c == 1 and raise MyError } assert_kind_of MyError, last_e attempt(4) { |c, prev_e| last_e = prev_e; c == 1 and raise MyError; c == 2 and raise ArgumentError } assert_kind_of ArgumentError, last_e end end end tins-1.32.1/tests/lines_file_test.rb0000644000004100000410000000513314353307475017457 0ustar www-datawww-datarequire 'test_helper' require 'tempfile' require 'tins/lines_file' module Tins class TinsLinesFileTest < Test::Unit::TestCase FILE = <, '1.2'.version assert_operator '1.2'.version, :<=, '1.2'.version assert_operator '1.2'.version, :>=, '1.2'.version assert_operator '1.2'.version, :==, '1.2'.version end def test_change s = '1.2' s.version.revision = 1 assert_equal '1.2.0.1', s s.version.revision += 1 assert_equal '1.2.0.2', s s.version.succ! assert_equal '1.2.0.3', s s.version.pred! assert_equal '1.2.0.2', s assert_raise(ArgumentError) { s.version.build -= 1 } s.version.major = 2 assert_equal '2.2.0.2', s s.version.minor = 1 assert_equal '2.1.0.2', s end def test_bump s = '1.2.3' assert_equal '2.0.0', s.version.bump(:major).to_s s = '1.2.3' assert_equal '1.3.0', s.version.bump(:minor).to_s s = '1.2.3' assert_equal '1.2.4', s.version.bump(:build).to_s s = '1.2.3' assert_equal '1.2.4', s.version.bump.to_s end def test_dup s = '1.2.3' v = s.version w = v.dup v.succ! assert_equal '1.2.4', v.to_s assert_equal '1.2.3', w.to_s end def test_clone s = '1.2.3' v = s.version w = v.clone v.succ! assert_equal '1.2.4', v.to_s assert_equal '1.2.3', w.to_s end end end tins-1.32.1/tests/time_dummy_test.rb0000644000004100000410000000135414353307475017520 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class TimeDummyTest < Test::Unit::TestCase require 'tins/xt/time_dummy' require 'time' def test_time_dummy time = Time.parse('2009-09-09 21:09:09') assert_not_equal time, Time.now Time.dummy = time assert_equal time, Time.now Time.dummy = nil assert_not_equal time, Time.now end def test_time_dummy_block time = Time.parse('2009-09-09 21:09:09') assert_not_equal time, Time.now Time.dummy time do assert_equal time, Time.now Time.dummy time + 1 do assert_equal time + 1, Time.now end assert_equal time, Time.now end assert_not_equal time, Time.now end end end tins-1.32.1/tests/secure_write_test.rb0000644000004100000410000000213114353307475020041 0ustar www-datawww-datarequire 'test_helper' require 'tempfile' require 'tins' module Tins class TinsSecureWriteTest < Test::Unit::TestCase module A extend SecureWrite end def test_secure_write assert_equal 4, A.secure_write(fn = File.join(Dir.tmpdir, "A_file.#$$"), 'test') assert_equal 4, A.secure_write(fn = File.join(Dir.tmpdir, "A_file.#$$")) { |f| f.write('test') } assert_equal 'test', File.read(fn) assert_raise(ArgumentError) { A.secure_write } end module B extend Write end module C def self.write(*args) args end extend Write end class ::IO extend Write end def test_write assert_equal 4, B.write(fn = File.join(Dir.tmpdir, "B_file.#$$"), 'test') assert_equal 4, B.write(fn = File.join(Dir.tmpdir, "B_file.#$$")) { |f| f.write('test') } assert_equal 4, IO.write(fn = File.join(Dir.tmpdir, "IO_file.#$$"), 'test') assert_equal 'test', File.read(fn) result = C.write(fn = File.join(Dir.tmpdir, "C_file.#$$"), 'test') assert_equal [ fn, 'test' ], result end end end tins-1.32.1/tests/bijection_test.rb0000644000004100000410000000071114353307475017311 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class BijectionTest < Test::Unit::TestCase def test_bijection assert_equal [ [ 1, 2 ], [ 3, 4 ] ], Tins::Bijection[ 1, 2, 3, 4 ].to_a.sort assert_raise(ArgumentError) do Tins::Bijection[1,2,3] end assert_raise(ArgumentError) do Tins::Bijection[1,2,3,2] end assert_raise(ArgumentError) do Tins::Bijection[1,2,1,3] end end end end tins-1.32.1/tests/dslkit_test.rb0000644000004100000410000001425314353307475016643 0ustar www-datawww-datarequire 'test_helper' require 'tins' class TL def initialize make_baz end extend Tins::ThreadLocal thread_local :foo extend Tins::ThreadLocal thread_local :foo2 do {} end include Tins::ThreadLocal def make_baz instance_thread_local :baz end extend Tins::ThreadGlobal thread_global :bar thread_global :bar2 do {} end end class IE def initialize(&block) @block = block end def exec instance_exec(&@block) end def foo :foo end end class C extend Tins::Constant constant :foo constant :bar, :baz end class DA extend Tins::DSLAccessor dsl_accessor :foo dsl_accessor :bar, :bar dsl_accessor :baz do :baz end dsl_accessor :quux, :qu, :ux dsl_reader :on, true dsl_reader :off, false dsl_reader :states do [ on, off ] end dsl_reader :abc, *%w[a b c] end class I include Tins::Interpreter def foo :foo end def y 2 end end class S include Tins::SymbolMaker end module K extend Tins::ConstantMaker end module D extend Tins::Deflect end class D3 < Tins::MethodMissingDelegator::DelegatorClass end require 'test/unit' require 'tempfile' class PoliteTest < Test::Unit::TestCase def setup @tl = TL.new @tl2 = TL.new @ie = IE.new { foo } @c = C.new @da = DA.new @i = I.new end def test_version assert_equal Tins::VERSION_ARRAY * '.', Tins::VERSION end def test_thread_local assert_nil @tl.foo @tl.foo = 1 assert_equal 1, @tl.foo new_foo = nil thread = Thread.new do @tl.foo = 2 new_foo = @tl.foo end thread.join assert_equal 2, new_foo assert_equal 1, @tl.foo assert_equal @tl.baz, @tl2.baz end def test_thread_local_with_default assert_kind_of Hash, @tl.foo2 @tl.foo2[:hi] = 1 assert_equal 1, @tl.foo2[:hi] thread = Thread.new do assert_kind_of Hash, @tl.foo2 assert_nil @tl.foo2[:hi] @tl.foo2[:hi] = 2 end thread.join assert_equal 1, @tl.foo2[:hi] end def test_instance_thread_local assert_nil @tl.baz @tl.baz = 1 assert_equal 1, @tl.baz new_foo = nil thread = Thread.new do @tl.baz = 2 new_foo = @tl.baz end thread.join assert_equal 2, new_foo assert_equal 1, @tl.baz assert_not_equal @tl.baz, @tl2.baz end def test_thread_global assert_nil @tl.bar @tl.bar = 1 assert_equal 1, @tl.bar new_bar = nil thread = Thread.new do @tl.bar = 2 new_bar = @tl.bar end thread.join assert_equal 2, new_bar assert_equal 2, @tl.bar end def test_thread_global_with_default assert_kind_of Hash, @tl.bar2 @tl.bar2[:hi] = 1 assert_equal 1, @tl.bar2[:hi] thread = Thread.new do assert_kind_of Hash, @tl.bar2 assert_equal 1, @tl.bar2[:hi] end thread.join assert_equal 1, @tl.bar2[:hi] end def test_instance_exec assert_equal :foo, @ie.foo assert_equal :foo, @ie.exec @ie.freeze assert_equal :foo, @ie.foo assert_equal :foo, @ie.exec end def test_constant assert_equal :foo, @c.foo assert_equal :baz, @c.bar end def test_dsl_accessor assert_nil @da.foo assert_equal :bar, @da.bar assert_equal :baz, @da.baz assert_equal [:qu, :ux], @da.quux @da.foo 1 @da.bar 2 @da.baz 3 assert_equal 1, @da.foo assert_equal 2, @da.bar assert_equal 3, @da.baz end def test_dsl_reader assert_equal true, @da.on assert_equal false, @da.off assert_raise(ArgumentError) do @da.on false end assert_equal [ @da.on, @da.off ], @da.states assert_equal %w[a b c], @da.abc @da.abc << 'd' assert_equal %w[a b c d], @da.abc @da.instance_variable_set :@abc, %w[a b c] assert_equal %w[a b c], @da.abc end def test_dsl_accessor_multiple assert_nil @da.foo assert_equal :bar, @da.bar @da.foo 1, 2 @da.bar [1, 2] assert_equal [1, 2], @da.foo assert_equal [1, 2], @da.bar @da.bar [1, 2, *@da.bar] assert_equal [1, 2] * 2, @da.bar end def test_interpreter assert_equal :foo, @i.interpret('foo') temp = Tempfile.new('foo') temp.write 'foo' temp.rewind assert_equal :foo, @i.interpret(temp) end def test_interpreter_with_args assert_equal 3, @i.interpret('|x| x + y', 1) temp = Tempfile.new('foo') temp.write '|x| x + y' temp.rewind assert_equal 3, @i.interpret(temp, 1) end def test_symbol_maker s = S.new assert_equal(:foo, s.instance_exec { foo }) assert_raise(NoMethodError) { s.instance_exec { foo 1 }} end def test_constant_maker assert_equal(:FOO, K::FOO) end def test_deflect_block assert_raise(NoMethodError) { 1.foo } assert !D.deflect?(Integer, :foo) D.deflect(Integer, :foo, Tins::Deflect::Deflector.new { :foo }) do assert_equal :foo, 1.foo assert D.deflect?(Integer, :foo) end assert !D.deflect?(Integer, :foo) assert_raise(NoMethodError) { 1.foo } end def test_deflect assert_raise(NoMethodError) { 1.foo } assert !D.deflect?(Integer, :foo) D.deflect_start(Integer, :foo, Tins::Deflect::Deflector.new { :foo }) assert_equal :foo, 1.foo assert D.deflect?(Integer, :foo) t = Thread.new do assert !D.deflect?(Integer, :foo) assert_raise(NoMethodError) { 1.foo } end t.join D.deflect_stop(Integer, :foo) assert !D.deflect?(Integer, :foo) assert_raise(NoMethodError) { 1.foo } end def test_deflect_method_missing assert_raise(NoMethodError) { 1.foo } assert !D.deflect?(Integer, :method_missing) D.deflect_start(Integer, :method_missing, Tins::Deflect::Deflector.new { :foo }) assert_equal :foo, 1.foo assert D.deflect?(Integer, :method_missing) t = Thread.new do assert !D.deflect?(Integer, :method_missing) assert_raise(NoMethodError) { 1.foo } end t.join D.deflect_stop(Integer, :method_missing) assert !D.deflect?(Integer, :method_missing) assert_raise(NoMethodError) { 1.foo } end def test_delegate_d3 d = D3.new [] assert_equal 0, d.size d.push 1 assert_equal [1], d.map { |x| x } d.push 2 assert_equal [1, 2], d.map { |x| x } d.push 3 assert_equal [1, 2, 3], d.map { |x| x } end end tins-1.32.1/tests/null_test.rb0000644000004100000410000000367714353307475016333 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class NullTest < Test::Unit::TestCase require 'tins/xt/null' def test_null assert_equal NULL, NULL.foo assert_equal NULL, NULL.foo.bar assert_equal 'NULL', NULL.inspect assert_equal '', NULL.to_s assert_equal 0, NULL.to_i assert_equal 0.0, NULL.to_f assert_equal [], NULL.to_a assert_equal 1, null(1) assert_equal 1, Null(1) assert_equal NULL, null(nil) assert_equal NULL, Null(nil) assert_equal NULL, NULL::NULL assert NULL.nil? assert NULL.blank? assert_equal nil, NULL.as_json assert_equal 'null', NULL.to_json end def test_null_plus assert_equal 1, null_plus(value: 1) assert_equal 1, NullPlus(value: 1) assert_kind_of Tins::NullPlus, null_plus(value: nil) assert_kind_of Tins::NullPlus, NullPlus(value: nil) assert_kind_of Tins::NullPlus, null_plus assert_kind_of Tins::NullPlus, NullPlus() assert_kind_of Tins::NullPlus, null_plus.foo assert_kind_of Tins::NullPlus, null_plus.foo.bar assert_kind_of Tins::NullPlus, NullPlus().foo assert_kind_of Tins::NullPlus, NullPlus().foo.bar assert null_plus.nil? assert null_plus().blank? assert_equal nil, null_plus().as_json assert_equal 'null', null_plus.to_json assert NullPlus().nil? assert NullPlus().blank? assert_equal nil, NullPlus().as_json assert_equal 'null', NullPlus().to_json end def foo 1 / 0 rescue => e null_plus(error: e) end def test_null_plus_caller_and_misc assert_match(/foo/, foo.caller.first) if foo.respond_to?(:caller_locations) assert_kind_of Thread::Backtrace::Location, foo.caller_locations.first assert_match(/foo/, foo.caller_locations.first.to_s) end assert_match(/foo/, foo.caller.first) assert_kind_of ZeroDivisionError, foo.error end end end tins-1.32.1/tests/concern_test.rb0000644000004100000410000000070714353307475016777 0ustar www-datawww-datarequire 'test_helper' require 'tins' class ConcernTest < Test::Unit::TestCase module AC extend Tins::Concern included do $included = self end def foo :foo end module ClassMethods def bar :bar end end end $included = nil class A include AC end def test_concern a = A.new assert_equal A, $included assert_equal :foo, a.foo assert_equal :bar, A.bar end end tins-1.32.1/tests/minimize_test.rb0000644000004100000410000000345514353307475017174 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class MinimizeTest < Test::Unit::TestCase class ::Array include Tins::Minimize end def test_minimize assert_equal [], [].minimize assert_equal [ 1..1 ], [ 1 ].minimize assert_equal [ 1..2 ], [ 1, 2 ].minimize assert_equal [ 1..1, 7..7 ], [ 1, 7 ].minimize assert_equal [ 1..3, 7..7, 11..14 ], [ 1, 2, 3, 7, 11, 12, 13, 14 ].minimize assert_equal [ 'A'..'C', 'G'..'G', 'K'..'M' ], [ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ].minimize end def test_minimize! assert_equal [], [].minimize! assert_equal [ 1..1 ], [ 1 ].minimize! assert_equal [ 1..2 ], [ 1, 2 ].minimize! assert_equal [ 1..1, 7..7 ], [ 1, 7 ].minimize! assert_equal [ 1..3, 7..7, 11..14 ], [ 1, 2, 3, 7, 11, 12, 13, 14 ].minimize! assert_equal [ 'A'..'C', 'G'..'G', 'K'..'M' ], [ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ].minimize! end def test_unminimize assert_equal [], [].unminimize assert_equal [ 1 ], [ 1..1 ].unminimize assert_equal [ 1, 2 ], [ 1..2 ].unminimize assert_equal [ 1, 7 ], [ 1..1, 7..7 ].unminimize assert_equal [ 1, 2, 3, 7, 11, 12, 13, 14 ], [ 1..3, 7..7, 11..14 ].unminimize assert_equal [ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ], [ 'A'..'C', 'G'..'G', 'K'..'M' ].unminimize end def test_unminimize! assert_equal [], [].unminimize! assert_equal [ 1 ], [ 1..1 ].unminimize! assert_equal [ 1, 2 ], [ 1..2 ].unminimize! assert_equal [ 1, 7 ], [ 1..1, 7..7 ].unminimize! assert_equal [ 1, 2, 3, 7, 11, 12, 13, 14 ], [ 1..3, 7..7, 11..14 ].unminimize! assert_equal [ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ], [ 'A'..'C', 'G'..'G', 'K'..'M' ].unminimize! end end end tins-1.32.1/tests/sexy_singleton_test.rb0000644000004100000410000000037314353307475020421 0ustar www-datawww-datarequire 'tins' class SexySingletonTest < Test::Unit::TestCase class Single include Tins::SexySingleton def foo :foo end end def test_foo assert_equal :foo, Single.instance.foo assert_equal :foo, Single.foo end end tins-1.32.1/tests/deep_dup_test.rb0000644000004100000410000000061014353307475017126 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class DeepDupTest < Test::Unit::TestCase def test_deep_dup a = [1,2,3] assert_equal a, a.deep_dup assert_not_same a, a.deep_dup end def test_deep_dup_proc f = lambda { |x| 2 * x } g = f.deep_dup assert_equal f[3], g[3] assert_equal f, g assert_same f, g end end end tins-1.32.1/tests/string_underscore_test.rb0000644000004100000410000000037114353307475021104 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class StringUnderscoreTest < Test::Unit::TestCase def test_underscore assert_equal 'foo_bar', 'FooBar'.underscore assert_equal 'foo/bar', 'Foo::Bar'.underscore end end end tins-1.32.1/tests/duration_test.rb0000644000004100000410000000414714353307475017177 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class DurationTest < Test::Unit::TestCase def test_short_to_s assert_equal '00:11:06', Tins::Duration.new(666).to_s end def test_to_s_with_days assert_equal '7+17:11:06', Tins::Duration.new(666666).to_s end def test_to_s_with_fractional_seconds assert_equal '00:11:06.123', Tins::Duration.new(666.123456).to_s end def test_to_s_with_days_and_fractional_seconds assert_equal '7+17:11:06.123', Tins::Duration.new(666666.123456).to_s end def test_format_without_precision assert_equal '0+00:11:06.123456', Tins::Duration.new(666.123456).format end def test_smart_format assert_equal '00:11:06.123', Tins::Duration.new(666.123456).format('%D') assert_equal '7+17:11:06.123', Tins::Duration.new(666666.123456).format('%D') end def test_predicate_days s = 0 assert_false Tins::Duration.new(s).days? s += 86_400 assert_true Tins::Duration.new(s).days? end def test_predicate_hours s = 0 assert_false Tins::Duration.new(s).hours? s += 3600 assert_true Tins::Duration.new(s).hours? end def test_predicate_minutes s = 0 assert_false Tins::Duration.new(s).minutes? s += 60 assert_true Tins::Duration.new(s).minutes? end def test_predicate_seconds s = 0 assert_false Tins::Duration.new(s).seconds? s += 1 assert_true Tins::Duration.new(s).seconds? end def test_predicate_fractional_seconds s = 0 assert_false Tins::Duration.new(s).fractional_seconds? s += 0.1 assert_true Tins::Duration.new(s).fractional_seconds? end def test_comparison t1 = Tins::Duration.new(666.23456) t2 = Tins::Duration.new(666.12345) assert_operator t1, :>, t2 end def test_negative_durations duration = Tins::Duration.new(-42) assert_equal '-0+00:00:42.000000', duration.format assert_equal '-00:00:42', duration.to_s assert_true duration.negative? assert_false Tins::Duration.new(42).negative? end end end tins-1.32.1/tests/require_maybe_test.rb0000644000004100000410000000105414353307475020175 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins require 'tins/xt/require_maybe' class RequireMaybeTest < Test::Unit::TestCase def test_require_maybe_failed executed = false require_maybe 'nix' do executed = true end assert executed, 'require did not fail' end def test_require_maybe_succeeded not_executed = true result = require_maybe 'tins' do not_executed = false end assert [ false, true ].include?(result) assert not_executed, 'require failed' end end end tins-1.32.1/tests/generator_test.rb0000644000004100000410000000175614353307475017343 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class GeneratorTest < Test::Unit::TestCase def setup @numeric = [ 1, 2, 3 ] @string = %w[a b c] @chars = 'abc' end def test_generator g = Tins::Generator[@numeric, @string] assert_equal 2, g.size g.add_dimension(@chars, :each_byte) assert_equal 3, g.size assert_equal\ [[1, "a", 97], [1, "a", 98], [1, "a", 99], [1, "b", 97], [1, "b", 98], [1, "b", 99], [1, "c", 97], [1, "c", 98], [1, "c", 99], [2, "a", 97], [2, "a", 98], [2, "a", 99], [2, "b", 97], [2, "b", 98], [2, "b", 99], [2, "c", 97], [2, "c", 98], [2, "c", 99], [3, "a", 97], [3, "a", 98], [3, "a", 99], [3, "b", 97], [3, "b", 98], [3, "b", 99], [3, "c", 97], [3, "c", 98], [3, "c", 99]], g.to_a end end end tins-1.32.1/tests/named_test.rb0000644000004100000410000000141214353307475016426 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class NamedTest < Test::Unit::TestCase def test_named_simple a = [ 1, 2, 3 ] a.named(:plus1, :map) { |x| x + 1 } assert_equal [ 2, 3, 4 ], a.plus1 Array.named(:odd, :select) { |x| x % 2 == 1 } assert_equal [ 3 ], a.plus1.odd end def foo(x, y, &block) block.call x * y end def test_more_complex Object.named(:foo_with_block, :foo) do |z| z ** 2 end assert_equal foo(2, 3) { |z| z ** 2 }, foo_with_block(2, 3) Object.named(:foo_23, :foo, 2, 3) assert_equal foo(2, 3) { |z| z ** 2 }, foo_23 { |z| z ** 2 } Object.named(:foo_2, :foo, 2) assert_equal foo(2, 3) { |z| z ** 2 }, foo_2(3) { |z| z ** 2 } end end end tins-1.32.1/tests/temp_io_test.rb0000644000004100000410000000233614353307475017004 0ustar www-datawww-data# encoding: utf-8 require 'test_helper' require 'tins/xt/temp_io' module Tins class TempIOTest < Test::Unit::TestCase def test_with_string returned = temp_io(content: 'foo') { |io| assert_equal 'foo', io.read :done } assert_equal returned, :done end def test_with_suffixed_name returned = temp_io(content: 'foo', name: 'foo.csv') { |io| assert_true io.path.end_with?('foo.csv') :done } assert_equal returned, :done end def test_with_proc returned = temp_io(content: -> { 'foo' }) { |io| assert_equal 'foo', io.read :done } assert_equal returned, :done end def test_with_proc_and_io_arg returned = temp_io(content: -> io { io << 'foo' }) { |io| assert_equal 'foo', io.read :done } assert_equal returned, :done end def test_as_enum enum = Tins::TempIO::Enum.new(chunk_size: 5, filename: 'foo') { |file| assert_kind_of File, file file << "hello" << "world" } assert_equal 'foo', enum.filename assert_equal "hello", enum.next assert_equal "world", enum.next assert_raise(StopIteration) { enum.next } end end end tins-1.32.1/tests/blank_full_test.rb0000644000004100000410000000360314353307475017457 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' require 'set' module Tins class BlankFullTest < Test::Unit::TestCase def test_blank assert !true.blank? assert false.blank? assert nil.blank? assert [].blank? assert ![23].blank? assert Set[].blank? assert !Set[23].blank? assert({}.blank?) assert !{ foo: 23 }.blank? assert "".blank? assert " ".blank? assert !"foo".blank? end def test_present assert true.present? assert !false.present? assert !nil.present? assert ![].present? assert [23].present? assert !Set[].present? assert Set[23].present? assert !{}.present? assert({ foo: 23 }.present?) assert !"".present? assert !" ".present? assert "foo".present? end def test_full assert_equal true, true.full? assert_nil false.full? assert_nil nil.full? assert_nil [].full? assert_equal [ 23 ], [ 23 ].full? assert_nil Set[].full? assert_equal Set[23], Set[23].full? assert_nil({}.full?) assert_equal({ foo: 23 }, { foo: 23 }.full?) assert_nil "".full? assert_nil " ".full? assert_equal "foo", "foo".full? assert_nil " ".full?(&:size) assert_equal 3, "foo".full?(&:size) assert_nil " ".full?(&:size) assert_equal 3, "foo".full?(&:size) assert_nil " ".full?(:size) assert_equal 3, "foo".full?(:size) assert_nil " ".full?(:size) assert_equal 3, "foo".full?(:size) end def test_all_full assert_equal [1, 2], [1, 2].all_full? assert_nil [nil, 2].all_full? assert_nil [1, ''].all_full? end def test_all_full_with_block [1, 2].all_full? do |x, y| assert_equal 1, x assert_equal 2, y end ['', 2].all_full? do |x, y| assert false end end end end tins-1.32.1/tests/go_test.rb0000644000004100000410000000503114353307475015750 0ustar www-datawww-datarequire 'test_helper' require 'tins/go' module Tins class GoTest < Test::Unit::TestCase include Tins::GO def test_empty_string r = go '', args = %w[a b c] assert_equal({}, r) assert_equal %w[a b c], args end def test_empty_args r = go 'ab:', args = [] assert_equal({ 'a' => false, 'b' => nil }, r) assert_equal [], args end def test_simple r = go 'ab:', args = %w[-b hello -a -c rest] assert_equal({ 'a' => 1, 'b' => 'hello' }, r) assert_equal %w[-c rest], args end def test_complex r = go 'ab:', args = %w[-a -b hello -a -bworld -c rest] assert_equal({ 'a' => 2, 'b' => 'hello' }, r) assert_equal %w[hello world], r['b'].to_a assert_equal %w[-c rest], args end def test_complex2 r = go 'ab:', args = %w[-b hello -aa -b world -c rest] assert_equal({ 'a' => 2, 'b' => 'hello' }, r) assert_equal %w[hello world], r['b'].to_a assert_equal %w[-c rest], args end def test_complex_frozen args = %w[-b hello -aa -b world -c rest] args = args.map(&:freeze) r = go 'ab:', args assert_equal({ 'a' => 2, 'b' => 'hello' }, r) assert_equal %w[hello world], r['b'].to_a assert_equal %w[-c rest], args end def test_mixed_rest r = go 'ab:e:', args = %w[-b hello -c rest -aa -b world -d rest -e] assert_equal({ 'a' => 2, 'b' => 'hello', 'e' => nil }, r) assert_equal %w[hello world], r['b'].to_a assert_equal %w[-c rest -d rest -e], args end def test_concatenated_argument_at_end r = go 'ab:e:', args = %w[-a -bhello] assert_equal({ 'a' => 1, 'b' => 'hello', 'e' => nil }, r) assert_equal [], args end def test_defaults r = go('bv:', args = %w[ -v bar ], defaults: { ?b => true, ?v => 'foo' }) assert_equal({ ?b => 1, 'v' => 'bar' }, r) assert_equal [], args r = go('bv:', args = %w[ -v bar ~b baz ], defaults: { ?b => true, ?v => 'foo' }) assert_equal({ ?b => false, 'v' => 'bar' }, r) assert_equal %w[ baz ], args r = go('bv:', args = %w[ -b -v bar ], defaults: { ?b => 22, ?v => 'foo' }) assert_equal({ ?b => 23, 'v' => 'bar' }, r) assert_equal [], args r = go('bv:', args = %w[ -b ], defaults: { ?b => false, ?v => 'foo' }) assert_equal({ ?b => 1, 'v' => 'foo' }, r) assert_equal [], args r = go('bv:', args = %w[ ], defaults: { ?b => false, ?v => 'foo' }) assert_equal({ ?b => false, 'v' => 'foo' }, r) assert_equal [], args end end end tins-1.32.1/tests/test_helper.rb0000644000004100000410000000032614353307475016624 0ustar www-datawww-dataif ENV['START_SIMPLECOV'].to_i == 1 require 'simplecov' SimpleCov.start do add_filter "#{File.basename(File.dirname(__FILE__))}/" end end begin require 'byebug' rescue LoadError end require 'test/unit' tins-1.32.1/tests/if_predicate_test.rb0000644000004100000410000000037614353307475017770 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class IfPredicateTest < Test::Unit::TestCase def test_if_predicate assert_equal :foo, true.if? && :foo assert_nil false.if? && :foo assert_nil nil.if? && :foo end end end tins-1.32.1/tins.gemspec0000644000004100000410000004143614353307475015150 0ustar www-datawww-data# -*- encoding: utf-8 -*- # stub: tins 1.32.1 ruby lib Gem::Specification.new do |s| s.name = "tins".freeze s.version = "1.32.1" s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Florian Frank".freeze] s.date = "2022-11-21" s.description = "All the stuff that isn't good/big enough for a real library.".freeze s.email = "flori@ping.de".freeze s.extra_rdoc_files = ["README.md".freeze, "lib/dslkit.rb".freeze, "lib/dslkit/polite.rb".freeze, "lib/dslkit/rude.rb".freeze, "lib/spruz.rb".freeze, "lib/tins.rb".freeze, "lib/tins/alias.rb".freeze, "lib/tins/annotate.rb".freeze, "lib/tins/ask_and_send.rb".freeze, "lib/tins/attempt.rb".freeze, "lib/tins/bijection.rb".freeze, "lib/tins/case_predicate.rb".freeze, "lib/tins/complete.rb".freeze, "lib/tins/concern.rb".freeze, "lib/tins/count_by.rb".freeze, "lib/tins/date_dummy.rb".freeze, "lib/tins/date_time_dummy.rb".freeze, "lib/tins/deep_const_get.rb".freeze, "lib/tins/deep_dup.rb".freeze, "lib/tins/dslkit.rb".freeze, "lib/tins/duration.rb".freeze, "lib/tins/expose.rb".freeze, "lib/tins/extract_last_argument_options.rb".freeze, "lib/tins/file_binary.rb".freeze, "lib/tins/find.rb".freeze, "lib/tins/generator.rb".freeze, "lib/tins/go.rb".freeze, "lib/tins/hash_symbolize_keys_recursive.rb".freeze, "lib/tins/hash_union.rb".freeze, "lib/tins/if_predicate.rb".freeze, "lib/tins/implement.rb".freeze, "lib/tins/limited.rb".freeze, "lib/tins/lines_file.rb".freeze, "lib/tins/lru_cache.rb".freeze, "lib/tins/memoize.rb".freeze, "lib/tins/method_description.rb".freeze, "lib/tins/minimize.rb".freeze, "lib/tins/module_group.rb".freeze, "lib/tins/named_set.rb".freeze, "lib/tins/null.rb".freeze, "lib/tins/once.rb".freeze, "lib/tins/p.rb".freeze, "lib/tins/partial_application.rb".freeze, "lib/tins/proc_compose.rb".freeze, "lib/tins/proc_prelude.rb".freeze, "lib/tins/range_plus.rb".freeze, "lib/tins/require_maybe.rb".freeze, "lib/tins/responding.rb".freeze, "lib/tins/secure_write.rb".freeze, "lib/tins/sexy_singleton.rb".freeze, "lib/tins/string_byte_order_mark.rb".freeze, "lib/tins/string_camelize.rb".freeze, "lib/tins/string_underscore.rb".freeze, "lib/tins/string_version.rb".freeze, "lib/tins/subhash.rb".freeze, "lib/tins/temp_io.rb".freeze, "lib/tins/temp_io_enum.rb".freeze, "lib/tins/terminal.rb".freeze, "lib/tins/thread_local.rb".freeze, "lib/tins/time_dummy.rb".freeze, "lib/tins/timed_cache.rb".freeze, "lib/tins/to.rb".freeze, "lib/tins/to_proc.rb".freeze, "lib/tins/token.rb".freeze, "lib/tins/uniq_by.rb".freeze, "lib/tins/unit.rb".freeze, "lib/tins/version.rb".freeze, "lib/tins/write.rb".freeze, "lib/tins/xt.rb".freeze, "lib/tins/xt/annotate.rb".freeze, "lib/tins/xt/ask_and_send.rb".freeze, "lib/tins/xt/attempt.rb".freeze, "lib/tins/xt/blank.rb".freeze, "lib/tins/xt/case_predicate.rb".freeze, "lib/tins/xt/complete.rb".freeze, "lib/tins/xt/concern.rb".freeze, "lib/tins/xt/count_by.rb".freeze, "lib/tins/xt/date_dummy.rb".freeze, "lib/tins/xt/date_time_dummy.rb".freeze, "lib/tins/xt/deep_const_get.rb".freeze, "lib/tins/xt/deep_dup.rb".freeze, "lib/tins/xt/dslkit.rb".freeze, "lib/tins/xt/expose.rb".freeze, "lib/tins/xt/extract_last_argument_options.rb".freeze, "lib/tins/xt/file_binary.rb".freeze, "lib/tins/xt/full.rb".freeze, "lib/tins/xt/hash_symbolize_keys_recursive.rb".freeze, "lib/tins/xt/hash_union.rb".freeze, "lib/tins/xt/if_predicate.rb".freeze, "lib/tins/xt/implement.rb".freeze, "lib/tins/xt/irb.rb".freeze, "lib/tins/xt/method_description.rb".freeze, "lib/tins/xt/named.rb".freeze, "lib/tins/xt/null.rb".freeze, "lib/tins/xt/p.rb".freeze, "lib/tins/xt/partial_application.rb".freeze, "lib/tins/xt/proc_compose.rb".freeze, "lib/tins/xt/proc_prelude.rb".freeze, "lib/tins/xt/range_plus.rb".freeze, "lib/tins/xt/require_maybe.rb".freeze, "lib/tins/xt/responding.rb".freeze, "lib/tins/xt/secure_write.rb".freeze, "lib/tins/xt/sexy_singleton.rb".freeze, "lib/tins/xt/string.rb".freeze, "lib/tins/xt/string_byte_order_mark.rb".freeze, "lib/tins/xt/string_camelize.rb".freeze, "lib/tins/xt/string_underscore.rb".freeze, "lib/tins/xt/string_version.rb".freeze, "lib/tins/xt/subhash.rb".freeze, "lib/tins/xt/temp_io.rb".freeze, "lib/tins/xt/time_dummy.rb".freeze, "lib/tins/xt/time_freezer.rb".freeze, "lib/tins/xt/to.rb".freeze, "lib/tins/xt/uniq_by.rb".freeze, "lib/tins/xt/write.rb".freeze] s.files = ["COPYING".freeze, "Gemfile".freeze, "README.md".freeze, "Rakefile".freeze, "examples/add_one.png".freeze, "examples/add_one.stm".freeze, "examples/bb3.png".freeze, "examples/bb3.stm".freeze, "examples/concatenate_compare.mtm".freeze, "examples/concatenate_compare.png".freeze, "examples/length_difference.mtm".freeze, "examples/length_difference.png".freeze, "examples/let.rb".freeze, "examples/mail.rb".freeze, "examples/minsky.rb".freeze, "examples/multiply.reg".freeze, "examples/null_pattern.rb".freeze, "examples/ones_difference-mtm.png".freeze, "examples/ones_difference-stm.png".freeze, "examples/ones_difference.mtm".freeze, "examples/ones_difference.stm".freeze, "examples/prefix-equals-suffix-reversed-with-infix.png".freeze, "examples/prefix-equals-suffix-reversed-with-infix.stm".freeze, "examples/recipe.rb".freeze, "examples/recipe2.rb".freeze, "examples/recipe_common.rb".freeze, "examples/subtract.reg".freeze, "examples/turing-graph.rb".freeze, "examples/turing.rb".freeze, "lib/dslkit.rb".freeze, "lib/dslkit/polite.rb".freeze, "lib/dslkit/rude.rb".freeze, "lib/spruz".freeze, "lib/spruz.rb".freeze, "lib/tins.rb".freeze, "lib/tins/alias.rb".freeze, "lib/tins/annotate.rb".freeze, "lib/tins/ask_and_send.rb".freeze, "lib/tins/attempt.rb".freeze, "lib/tins/bijection.rb".freeze, "lib/tins/case_predicate.rb".freeze, "lib/tins/complete.rb".freeze, "lib/tins/concern.rb".freeze, "lib/tins/count_by.rb".freeze, "lib/tins/date_dummy.rb".freeze, "lib/tins/date_time_dummy.rb".freeze, "lib/tins/deep_const_get.rb".freeze, "lib/tins/deep_dup.rb".freeze, "lib/tins/dslkit.rb".freeze, "lib/tins/duration.rb".freeze, "lib/tins/expose.rb".freeze, "lib/tins/extract_last_argument_options.rb".freeze, "lib/tins/file_binary.rb".freeze, "lib/tins/find.rb".freeze, "lib/tins/generator.rb".freeze, "lib/tins/go.rb".freeze, "lib/tins/hash_symbolize_keys_recursive.rb".freeze, "lib/tins/hash_union.rb".freeze, "lib/tins/if_predicate.rb".freeze, "lib/tins/implement.rb".freeze, "lib/tins/limited.rb".freeze, "lib/tins/lines_file.rb".freeze, "lib/tins/lru_cache.rb".freeze, "lib/tins/memoize.rb".freeze, "lib/tins/method_description.rb".freeze, "lib/tins/minimize.rb".freeze, "lib/tins/module_group.rb".freeze, "lib/tins/named_set.rb".freeze, "lib/tins/null.rb".freeze, "lib/tins/once.rb".freeze, "lib/tins/p.rb".freeze, "lib/tins/partial_application.rb".freeze, "lib/tins/proc_compose.rb".freeze, "lib/tins/proc_prelude.rb".freeze, "lib/tins/range_plus.rb".freeze, "lib/tins/require_maybe.rb".freeze, "lib/tins/responding.rb".freeze, "lib/tins/secure_write.rb".freeze, "lib/tins/sexy_singleton.rb".freeze, "lib/tins/string_byte_order_mark.rb".freeze, "lib/tins/string_camelize.rb".freeze, "lib/tins/string_underscore.rb".freeze, "lib/tins/string_version.rb".freeze, "lib/tins/subhash.rb".freeze, "lib/tins/temp_io.rb".freeze, "lib/tins/temp_io_enum.rb".freeze, "lib/tins/terminal.rb".freeze, "lib/tins/thread_local.rb".freeze, "lib/tins/time_dummy.rb".freeze, "lib/tins/timed_cache.rb".freeze, "lib/tins/to.rb".freeze, "lib/tins/to_proc.rb".freeze, "lib/tins/token.rb".freeze, "lib/tins/uniq_by.rb".freeze, "lib/tins/unit.rb".freeze, "lib/tins/version.rb".freeze, "lib/tins/write.rb".freeze, "lib/tins/xt.rb".freeze, "lib/tins/xt/annotate.rb".freeze, "lib/tins/xt/ask_and_send.rb".freeze, "lib/tins/xt/attempt.rb".freeze, "lib/tins/xt/blank.rb".freeze, "lib/tins/xt/case_predicate.rb".freeze, "lib/tins/xt/complete.rb".freeze, "lib/tins/xt/concern.rb".freeze, "lib/tins/xt/count_by.rb".freeze, "lib/tins/xt/date_dummy.rb".freeze, "lib/tins/xt/date_time_dummy.rb".freeze, "lib/tins/xt/deep_const_get.rb".freeze, "lib/tins/xt/deep_dup.rb".freeze, "lib/tins/xt/dslkit.rb".freeze, "lib/tins/xt/expose.rb".freeze, "lib/tins/xt/extract_last_argument_options.rb".freeze, "lib/tins/xt/file_binary.rb".freeze, "lib/tins/xt/full.rb".freeze, "lib/tins/xt/hash_symbolize_keys_recursive.rb".freeze, "lib/tins/xt/hash_union.rb".freeze, "lib/tins/xt/if_predicate.rb".freeze, "lib/tins/xt/implement.rb".freeze, "lib/tins/xt/irb.rb".freeze, "lib/tins/xt/method_description.rb".freeze, "lib/tins/xt/named.rb".freeze, "lib/tins/xt/null.rb".freeze, "lib/tins/xt/p.rb".freeze, "lib/tins/xt/partial_application.rb".freeze, "lib/tins/xt/proc_compose.rb".freeze, "lib/tins/xt/proc_prelude.rb".freeze, "lib/tins/xt/range_plus.rb".freeze, "lib/tins/xt/require_maybe.rb".freeze, "lib/tins/xt/responding.rb".freeze, "lib/tins/xt/secure_write.rb".freeze, "lib/tins/xt/sexy_singleton.rb".freeze, "lib/tins/xt/string.rb".freeze, "lib/tins/xt/string_byte_order_mark.rb".freeze, "lib/tins/xt/string_camelize.rb".freeze, "lib/tins/xt/string_underscore.rb".freeze, "lib/tins/xt/string_version.rb".freeze, "lib/tins/xt/subhash.rb".freeze, "lib/tins/xt/temp_io.rb".freeze, "lib/tins/xt/time_dummy.rb".freeze, "lib/tins/xt/time_freezer.rb".freeze, "lib/tins/xt/to.rb".freeze, "lib/tins/xt/uniq_by.rb".freeze, "lib/tins/xt/write.rb".freeze, "tests/annotate_test.rb".freeze, "tests/ask_and_send_test.rb".freeze, "tests/attempt_test.rb".freeze, "tests/bijection_test.rb".freeze, "tests/blank_full_test.rb".freeze, "tests/case_predicate_test.rb".freeze, "tests/concern_test.rb".freeze, "tests/count_by_test.rb".freeze, "tests/date_dummy_test.rb".freeze, "tests/date_time_dummy_test.rb".freeze, "tests/deep_const_get_test.rb".freeze, "tests/deep_dup_test.rb".freeze, "tests/delegate_test.rb".freeze, "tests/dslkit_test.rb".freeze, "tests/duration_test.rb".freeze, "tests/dynamic_scope_test.rb".freeze, "tests/expose_test.rb".freeze, "tests/extract_last_argument_options_test.rb".freeze, "tests/file_binary_test.rb".freeze, "tests/find_test.rb".freeze, "tests/from_module_test.rb".freeze, "tests/generator_test.rb".freeze, "tests/go_test.rb".freeze, "tests/hash_symbolize_keys_recursive_test.rb".freeze, "tests/hash_union_test.rb".freeze, "tests/if_predicate_test.rb".freeze, "tests/implement_test.rb".freeze, "tests/limited_test.rb".freeze, "tests/lines_file_test.rb".freeze, "tests/lru_cache_test.rb".freeze, "tests/memoize_test.rb".freeze, "tests/method_description_test.rb".freeze, "tests/minimize_test.rb".freeze, "tests/module_group_test.rb".freeze, "tests/named_set_test.rb".freeze, "tests/named_test.rb".freeze, "tests/null_test.rb".freeze, "tests/p_test.rb".freeze, "tests/partial_application_test.rb".freeze, "tests/proc_compose_test.rb".freeze, "tests/proc_prelude_test.rb".freeze, "tests/range_plus_test.rb".freeze, "tests/require_maybe_test.rb".freeze, "tests/responding_test.rb".freeze, "tests/rotate_test.rb".freeze, "tests/scope_test.rb".freeze, "tests/secure_write_test.rb".freeze, "tests/sexy_singleton_test.rb".freeze, "tests/string_byte_order_mark_test.rb".freeze, "tests/string_camelize_test.rb".freeze, "tests/string_underscore_test.rb".freeze, "tests/string_version_test.rb".freeze, "tests/subhash_test.rb".freeze, "tests/temp_io_test.rb".freeze, "tests/test_helper.rb".freeze, "tests/time_dummy_test.rb".freeze, "tests/time_freezer_test.rb".freeze, "tests/to_test.rb".freeze, "tests/token_test.rb".freeze, "tests/uniq_by_test.rb".freeze, "tests/unit_test.rb".freeze, "tins.gemspec".freeze] s.homepage = "https://github.com/flori/tins".freeze s.licenses = ["MIT".freeze] s.rdoc_options = ["--title".freeze, "Tins - Useful stuff.".freeze, "--main".freeze, "README.md".freeze] s.required_ruby_version = Gem::Requirement.new(">= 2.0".freeze) s.rubygems_version = "3.3.17".freeze s.summary = "Useful stuff.".freeze s.test_files = ["tests/annotate_test.rb".freeze, "tests/ask_and_send_test.rb".freeze, "tests/attempt_test.rb".freeze, "tests/bijection_test.rb".freeze, "tests/blank_full_test.rb".freeze, "tests/case_predicate_test.rb".freeze, "tests/concern_test.rb".freeze, "tests/count_by_test.rb".freeze, "tests/date_dummy_test.rb".freeze, "tests/date_time_dummy_test.rb".freeze, "tests/deep_const_get_test.rb".freeze, "tests/deep_dup_test.rb".freeze, "tests/delegate_test.rb".freeze, "tests/dslkit_test.rb".freeze, "tests/duration_test.rb".freeze, "tests/dynamic_scope_test.rb".freeze, "tests/expose_test.rb".freeze, "tests/extract_last_argument_options_test.rb".freeze, "tests/file_binary_test.rb".freeze, "tests/find_test.rb".freeze, "tests/from_module_test.rb".freeze, "tests/generator_test.rb".freeze, "tests/go_test.rb".freeze, "tests/hash_symbolize_keys_recursive_test.rb".freeze, "tests/hash_union_test.rb".freeze, "tests/if_predicate_test.rb".freeze, "tests/implement_test.rb".freeze, "tests/limited_test.rb".freeze, "tests/lines_file_test.rb".freeze, "tests/lru_cache_test.rb".freeze, "tests/memoize_test.rb".freeze, "tests/method_description_test.rb".freeze, "tests/minimize_test.rb".freeze, "tests/module_group_test.rb".freeze, "tests/named_set_test.rb".freeze, "tests/named_test.rb".freeze, "tests/null_test.rb".freeze, "tests/p_test.rb".freeze, "tests/partial_application_test.rb".freeze, "tests/proc_compose_test.rb".freeze, "tests/proc_prelude_test.rb".freeze, "tests/range_plus_test.rb".freeze, "tests/require_maybe_test.rb".freeze, "tests/responding_test.rb".freeze, "tests/rotate_test.rb".freeze, "tests/scope_test.rb".freeze, "tests/secure_write_test.rb".freeze, "tests/sexy_singleton_test.rb".freeze, "tests/string_byte_order_mark_test.rb".freeze, "tests/string_camelize_test.rb".freeze, "tests/string_underscore_test.rb".freeze, "tests/string_version_test.rb".freeze, "tests/subhash_test.rb".freeze, "tests/temp_io_test.rb".freeze, "tests/test_helper.rb".freeze, "tests/time_dummy_test.rb".freeze, "tests/time_freezer_test.rb".freeze, "tests/to_test.rb".freeze, "tests/token_test.rb".freeze, "tests/uniq_by_test.rb".freeze, "tests/unit_test.rb".freeze, "tests/annotate_test.rb".freeze, "tests/ask_and_send_test.rb".freeze, "tests/attempt_test.rb".freeze, "tests/bijection_test.rb".freeze, "tests/blank_full_test.rb".freeze, "tests/case_predicate_test.rb".freeze, "tests/concern_test.rb".freeze, "tests/count_by_test.rb".freeze, "tests/date_dummy_test.rb".freeze, "tests/date_time_dummy_test.rb".freeze, "tests/deep_const_get_test.rb".freeze, "tests/deep_dup_test.rb".freeze, "tests/delegate_test.rb".freeze, "tests/dslkit_test.rb".freeze, "tests/duration_test.rb".freeze, "tests/dynamic_scope_test.rb".freeze, "tests/expose_test.rb".freeze, "tests/extract_last_argument_options_test.rb".freeze, "tests/file_binary_test.rb".freeze, "tests/find_test.rb".freeze, "tests/from_module_test.rb".freeze, "tests/generator_test.rb".freeze, "tests/go_test.rb".freeze, "tests/hash_symbolize_keys_recursive_test.rb".freeze, "tests/hash_union_test.rb".freeze, "tests/if_predicate_test.rb".freeze, "tests/implement_test.rb".freeze, "tests/limited_test.rb".freeze, "tests/lines_file_test.rb".freeze, "tests/lru_cache_test.rb".freeze, "tests/memoize_test.rb".freeze, "tests/method_description_test.rb".freeze, "tests/minimize_test.rb".freeze, "tests/module_group_test.rb".freeze, "tests/named_set_test.rb".freeze, "tests/named_test.rb".freeze, "tests/null_test.rb".freeze, "tests/p_test.rb".freeze, "tests/partial_application_test.rb".freeze, "tests/proc_compose_test.rb".freeze, "tests/proc_prelude_test.rb".freeze, "tests/range_plus_test.rb".freeze, "tests/require_maybe_test.rb".freeze, "tests/responding_test.rb".freeze, "tests/rotate_test.rb".freeze, "tests/scope_test.rb".freeze, "tests/secure_write_test.rb".freeze, "tests/sexy_singleton_test.rb".freeze, "tests/string_byte_order_mark_test.rb".freeze, "tests/string_camelize_test.rb".freeze, "tests/string_underscore_test.rb".freeze, "tests/string_version_test.rb".freeze, "tests/subhash_test.rb".freeze, "tests/temp_io_test.rb".freeze, "tests/time_dummy_test.rb".freeze, "tests/time_freezer_test.rb".freeze, "tests/to_test.rb".freeze, "tests/token_test.rb".freeze, "tests/uniq_by_test.rb".freeze, "tests/unit_test.rb".freeze] if s.respond_to? :specification_version then s.specification_version = 4 end if s.respond_to? :add_runtime_dependency then s.add_development_dependency(%q.freeze, ["~> 1.12.0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, ["~> 3.1"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_runtime_dependency(%q.freeze, [">= 0"]) else s.add_dependency(%q.freeze, ["~> 1.12.0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, ["~> 3.1"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) end end tins-1.32.1/examples/0000755000004100000410000000000014353307475014434 5ustar www-datawww-datatins-1.32.1/examples/recipe2.rb0000755000004100000410000000333514353307475016321 0ustar www-datawww-data#!/usr/bin/env ruby require 'tins/xt' $:.unshift 'examples' require 'recipe_common' class Cup < Unit; end class Teaspoon < Unit; end class Tablespoon < Unit; end class Flour < Ingredient; end class Bakingpowder < Ingredient; end class Salt < Ingredient; end class Egg < Ingredient; end class Milk < Ingredient; end class Butter < Ingredient; end class Recipe < Tins::BlankSlate.with(:respond_to?, :instance_exec, :inspect, /^deflect/) include Tins::Deflect def initialize(&block) @ingredients = [] deflector = Deflector.new do |number, id, name| if unit = Unit.unit(name, number) unit else ingredient = Ingredient.ingredient(name, number) @ingredients << ingredient end end deflect_start(Numeric, :method_missing, deflector) deflector2 = Deflector.new do |unit, id, name| ingredient = Ingredient.ingredient(name, unit) @ingredients << ingredient end deflect_start(Unit, :method_missing, deflector2) instance_exec(&block) ensure deflect_stop(Numeric, :method_missing) if deflect?(Numeric, :method_missing) deflect_stop(Unit, :method_missing) if deflect?(Unit, :method_missing) end attr_reader :ingredients def to_a @ingredients end alias to_ary to_a def to_s to_a * "\n" end end class RecipeInterpreter def recipe(&block) Recipe.new(&block) end end recipe_source = <M_Pm%@ɓ'{I_U[[̗}=x>ضm=E `@ (Ya\4rСC{#c@&@zB t/++C 06:uWZeooqFܵA&uk,}}CY@@Q(K,A.BKLLˉ'֯_@ .;v "::֭[ԃxↆ3f.P BP.%%jhhx"3g/ݻ7k֬ VM;otl+ (cddݷmk``zԨQ&M:z(y5bĈ#G9rUC:2ꫂr9eQ "FMpy`Q:FA`Q:FA`Q:FA`Q:FA`端ںuk_P455|jsss_4k/ʕ+=zԥܽ{cƌr*̙3*׭[׭[7B(!!a{9sj-[nŊpJ_W{y.]r 233 xc( t@UWW2.%%Sݓ'O\;w޶G 2]##""$ɁI'O d2蚯Ӈѣ:V?N]p5klذaСj6ɯe2۷?v@=YyyyC 6mږ-[o- \.o߾7n܀;;ZBtJmm lM*444'Ǝf t/^=zTAݹsux/BA耎[ vvv4xORiVVVrr2%:p>,&&& 6/_y<ի: `'SPP0x]vQج[~~oVV)<`VuuuA\xАfuP(|>AMMM䇐yxx$%%Qx86x geeQzzz...'Oζiz:m%KN<9zhZt)SH$ZXamHKKDN@ P(th,,,lҤI?8P(D2p,: ӦMܹs'33ufnncn$7|'411a:vܹiӦ#Gxzz2y\@; %++룏>ZjդI>P(+BŋSN1bė_~ѡS td|>2ccc# ttWUUɓ vZܵ '''%###ܾ*Bz:: `An_uyܵ @ ]`tt}ƍ߾*0TGw@蜼ٳgϟ?kPX\\,qh[jkkLҧOw-oeee ! "22ŋ -}YWXBG[رcj* Cxz+N>vZܵP=-$J}~A~AA̙3#"">c`hϧ]|ygʔ)Bp͸Kk:Z~xR4))O>/))|* /BGH$#GHRPSSSIIIII'|B>b3@PTTP(Ytd2LwEGGd2uH ={ w!^:fmvWWW3_R'X:BG;v\.?+$O͵V?nN Yf}gY<z:Zn$kݻw r{}aÆa`.xYjjjk+>;w?ql=Am6wwwUu@ ~:*=C{x;w}ւUl̬[np[Gk)@' 8k?nkk<66UKEEEmmszںuj4jAٚU() thaCCׯ5 !iӦNhזFFFAAAoUl 6b:;r}||lmmcccB4z5Qڷ O͵v9n8k777B F t6BGAnРA\.!rkV߸q#5Qڷ) ) v- .\iii|?tМ"|]"r9 J:Ϗݳg /W(K,AR]e|$r| \ai%444\2 @Fbbb\\\N8~z k%o!diiijj CD"ʕ+B BFwADtt[MKV:Lضmٳg7 rɑ,* ZxqCCÌ3ꨭSMM thx\ \ f͚6_pE3g466^dݻwo֬Ys"6mv,奭 th7uT2,8Ό3 6_k``3jԨ0"ȑ#NNNTey]Kyi+˜vxRedPP\.W,9̺5@PZZ*Jyyw!J:`,^OOnh^z:ZB >:੹} tWo[Wh"j@"<w!2:?}tB LLLpV>dҽ/RYYzjZ҂rrvrppr?@TZZ: >Ro,a9\.KIGKA0- e2X,Rf!h:y{{7 ~qY`a8p`@7K`)/MᆱG~p<=='M$ 5Ea Nޒ4@ (** *ߟLhxx84P(lhhx)B t0puuEzj\%aZvvvvvvPPB2""wEޞýdÜc\r!m``. r!t4N:XVVo߾}IRБ#GOixj th$Jwݷo߱cǚݼy3<<<<<޽{iiicƌ۷ݻO5-ׯ_>wܞ={'%%X+gذaIII/^ٳܹsׯ____f 5P6&&G\.7""͛y͛7#""\n=bbbjkkSرw@E:VVV|>?***??-EEE|+++X\YYIGZ 55!s܅U@PL$DǏǏE"H$*//Nz*B* tR\\,bӧOjӧbX$Sղhllr]P>>wdKc@ ]2VbTeOO9s8;;edd5 w]m5jԥKҜ̙e]`i0wYD" B BCC_~zhh(AB066V"ஈFuuuA=zw! t Z,x[nuGm۶mƌU i]t-rX,iQ;ҼܹC߁lmmׯ_O_&: S"H S$//Юv%ə3gW|hΝ666WB/ƕwUUUEGG#|||;СC>9aH$ߦjW_uiD"###rWYY vh͚5r\Pz !dmmM߱O>uT4)**׷Ϟ=eBԢgϞb rOQQ%ͶI٥z;g}6p@4ѭɉݻwcT?lذ.!jFUWWXZZ oi̙\v?leeE!t%t9}ӧO˔WHNrppp8׮] b䛊hhh W^>ΥK pwwB˫<<55!'P۸ҝ;wB> tə0aA={_>tjjjrrr֯_okkkaaNCSWWyfr\ĉ)_7c!jUA?~M9t>3CfHՍ/R~OmΟ?occJ6׽{͛7>6OoA``2+!t}P( $ jANӧ6`i"mrV+W¼4bVdvv6ݔ#w LKK# |.˗B-`,Ŝ4򎲋Kll,x$Irrr~~~mܹs RӧO<(ؿ?*XqZZ+ WW)S<|077XA,_חt(tH7n &9;;S8+4 |)SΟ?OIaXgggr7l onҥFFFܴiL&@.MvlsCsNDDdz/_]]^|)ɹZѣA.t@$EGGWTTஈJfff"wEԻqB6,::'ODGGDD95::ɓ'+˗/BO]<\,w֍a*77wE%w֭X,օwͷlق :oxyoy}uֽ{ȹvvv3#W]mSSe˖gϞӧτ pr}={~]l)BhfPK IDAT6/[,??Ν>D(Yݵ֬Y# k%$$丸 2d˖-B8;;COG(%i\S媵S^^.LMM [OJbDDDh]2vعst>}*̌:X$O7-,,|||=zDE?1b*@gAPehhHΥxa^x!>|د_ݻ:u5ط~₻ Y:8qA+W#Gܻwݽ{744WMM {,۷oϗJ CcǾ{ >..ɉʕ+/dff999ũvj\\u:ud@!ݿ G*"H6l@Fϔ)SLp7lؠഴ4;;;77[nٔ*--Eѱ3,Ya{ݻ)kӧ#F044ܹs'Umj\n``g܅NQ]LLL֮]p1MMM(ZNf'ww wS`p v܉?>x111{GY^^px\s C%\iӦH ,̘1#+++55K X@h*?~ѣG˖-(ěZ^zeff~}lA tnܸq /&$$|WW9sfmm-P($.t BkZmo۷E"B4:hР㮈^ӧ С͛===Ǎyw}}}> B:Ԩܽ{EضçMrJL"Z888| tc7o<܅A__?..n׮]6l=zgpWD=.=:mKLiӦ9syYǏ4ʕ+ˡ<5:HJJ*..^t)B:s޽{nݺw9 46l0fwww܅t{'OFFFᮈ2:uٳgQ"'&&;vlذaZ;:ڴiS^>܅t\"J tiP@(~w!:jسgϒ%K3233'N8nܸ5kr6:jٶmޜ9sp";vl޼o d\5 tT'J7op&.?=͛7oԨQ ^HHHfffEEŠA]4, tTӽ{~G ˗4hA@PUUU]]Ul۶$22w!4255=xڵk͚5K#$AtYSSw-"bٲe)))gΜ]QA:,eӧOIygeee 0ȑ#i a9.۸qĉɞptt %NlܸqРAÇ]{EEE߼yԜ t:VZZ;T6hР,r*z:,ӱ8KK3f.DXYYZ~B t:P__믿.X@__w-=zFz z : BZhB4ĉ\B.?x%&- Eqq1Bxeiiу޷o9vSN]  drKy)X = &333AGedd.JX>O.?A̶ṉ@WAO r!P(*++wMW_}'UeAf:on.MMM ӣG4hPbb"4Z``rG}86yCeeeJRЍ72 .,Zhʔ)t/?` AIIIDf~ƍ'LK`:\.f4k֬ Z3.yCee%τ$$$t~wUUU 0`…/d2YiizeZ@輡kX͛CBBԣ5k,X@B1c͛7lr)':wm濺m;vС/"99Y.s89s樼Ja'] +W̟??>>5˗/ϧ83^n;vlFFF]]kL/_\zjm\XXι`ȼgώ5 !dooOP(ܼys]]̙rB\.722R.cV\vM__A TkpРANNNkNT*߿?B/99YPD"ݻ⊊ BnCCuׯ===[MxoCn nfaaH$222211D!___D`s\ru\V@Ǵ6t$Ill@ "44gbAfffٌ >vZP\GEEQ@0tb Nj}v'_X]]b KKK>Ckt??? Z_aYm_S\t5*t***bq D"ѣGThױ'888++:AkcǎWp87onp5NiiH$211122Dj6NDppK(tqqqAx<q##bkͧSTToaa!={Fa㍍B( 11Arss>}WX>εй~DDϷ}MdlODä{-Y\ѱGp5FNVVVpp0qpp}53MKK{BJW5?}k-as%rH{||<{iiiBFkpƄNbbb@@Bw9xL&[ύ7"""8@ s:r>>>'&&b6w툈gcc#pW\9_~#G<="EGGԞsS:... 6{IttrjOii)4kĮ!'8;;s܈7nந˞?"E}}=NYl /_bkkkr͝;wBAAAHHۺu:?dCCCwwsfffv ҫWbccmmmɩ=W6G 84&Ċh333rMAA <ֶ)66H$gΜ!_˺;wp8]zHGGGrjիWUn/^ %k\ӧB%%%I4O},,,._LGiii#GDDa&Mj~㣏>bx"h= Ça:IOO'=<<D_®~Q+wޥH9 X*dEEE۷o'ׅ@mܸ;mh: "44t޽zpD{g&u֭ 333SByjjjrrr֯_okkkaaNCoHKK;v,yC–'Nzw(lm\ws}U')Cf{ B.zW\INTH$:tPUUH$IR [=B(??f纫(9+WoZv [^^^TTdz􍎍0arŋm?ZU9fС4k@ 6n}k1W\AAH$244455DԶuVwwwrL&ۺuw_T#z.L.tO8JNNFZCZs!1]ӧObH$Fzz^kΝ;G@*>}>J理Bbcc{IoygXXXAAjkk8P\3pi9S[nzzzo-#8NO_PPPm5SL9)уxMZnmʕzzzz/n sNjjjbcc8Nhh(,qVVV|>?***//wEJs>..ɉ)d_*//D"Us l됧'B( %%wEj)..Dbӧ+b8:-C" 8w:r~X,ң\Zg+tHr<11!)ݽ{744HAl %C}cU233i5NNNqqq+oee%++++DN!kOMs[aC ȩ=eee | -B06T<~4.ϵƥ)4,td2ٚ5k\nhhh^^X,677'TCP($"44r|̘1\.Rƅ\t ]ISRR2|p##xcbb,--ɩ=ž<׀*4GGG@¿cԞANLQNݻ:q8ղ ;׀ _~?BBo=ڵkM*Oټys;|>ۻTAW1pX: B"̘1P5K95..{777wh &#055򲳳!k\? @n\} 2___ 'NPٳgɭlll >7odϭ#wSSSrb1 g\ۓ䧟~]`Ydgg BWW۷ow==QFڵA4IIIApܐ􂃃 Eff%Ks=t˗)tN8ajj:rH5o⴯ !t!:_jՐ!C?YYY={tssx͚5kĉ4yk֬?~9sOKKK$HBt47dffZYY5322 q\nnnyyyHҨ/~ڸqM122(-ڦ,X 44R;ѣGL} Ѵ̨3gNbbݻg͚ di鴃C {nח9::EzjرɧOf&q!M>̙3/^/**RrssCvBѣG.] dX.p8~~~W^U155]:Çd/^$'0oOx…ݻc%ڭ:a۷o>G  211?"###""6oތ؀w=z۱c,,,>:BH"p\Ϗ[xqEE"ziU:FC#Gӧϱcp5jkk Mk֬qqq?~~~mY.؀+W>rGlqIO~mBddyxxxUU \-Nzo ۫Wȉr=+WÇg,qPJ$BhҤI'O<{qjjjpZߺ"xj=nܸ߿yZv{wSSSܹ{=w9=trrrF흘Ȇ,R8p`JJJiiiHHׯq8NϞ=#G;))%oyyԿ3g?|=h O=֖=X|y;拉=﨣͉ ;B&88:ǔ͗WJgϞ}رc:Zpy-^\\Ķg,RHMMχܡϫqh ?0--ɓt_^)?ətݻw:tLJէWJ?vؕ+WfϞ OQB(x<(?OmTH$! :رc'NOqע |3iW\7oއ~((lZ! >;v̚5k<#{:/^ܰaƍY8mJiƌs΍zZ4l SSS1eʔHj v\^)ϮMMMk00#C>H$ Mk.HѸk0X:g\\ƍY>*ZlzEGG-[;v w-M*vXt9tϟ?m4xFނD"aT:uY.\˹wl QCocЉW矹\.ٲUXc?ӆ lmmi*Z bŊ]ׯ_ojj_9Nn|IZlϦv5jԨSN6 w9TTTobbsNrhУXExۼϞ=v˥& ZXXr \P(R)B(11q„ Xk󓒒޽˶%bYq999Hnp5_Sօ˫ǏlڴIS!dllCUhhرc,X@v@ |=S#H>ɉ(ЧO?7nmyyy7n+Vh\ccA::D"Yr%dԩzzz,XA7:mҥk֬] -_w:8t tޝ0q?dqCիW#bbbpF+Wl `w%mllo׺uqF_T~8NHHtH=Tw͙3G& K*j-/^_.);;pig޽{y<ޣG@8qB!am˖-qPWWףGxSNHtYnԩS{Ic1#z-XPb޼y={;;m200ЁȌj'222BE &L@Akaȯ_ZZ6'oE_|||?M2EP{**sε]7!̴QMMц hͼ^z^VVt¢w!׿L?[om>|\?˗3OM]]3x8coҥ}opBܵtك|}}.b֭]6o {͇3744, 3fl޼YC!}%=/^3\ ŋoݺz[$%%qܐt)%:#FuӢE>} 3_ -,,v؁ ̚\kFgϝ;_ms=3F;wY >.\XRR|X:.\иA\\\ƌv-CG.gff>K5V-:uTnn.BNk:>|,/Ǝk.܅2t_ׯ_?,Zqܹsڵ n'Zݻw=<\SSZNAA R3e2١Cpt#HpUDh"kkkKKŋ744t999~5W( &M 9~t-88Xwh#Gu}̙%%%+<{ !|( HMM%bȑ/_ܻwo'_)pe˖6wIɓ'¸su>!aÆfgg.x!dmm.pBRRҒ%K߯_K۷ڵk|y}}=Q8 秦8qYYYi߽Q~bo?YPPn:uyBS1]FޘxoGڿ?ΚP(Mի{S&W(4ZZ !G?(8=:Ul?!J~K~|J@@@gt$''ԔUwʕe˖9::R3rssoݺEa,'$###$$VOO{l[o.B!:Nyy9B[nd픔dddxyy}7l{C^ۛv}}}>~Sl'D$]p!33իW۶m;p@TTMOoNSSBc*^|200 %㲲R iiiiii|rЦMhUU Dr…ׯ744޽[f 4iSUYY) &M:wwUg}×/_O!j;Ŕ`[a#?LRV" Iq\/B޽{T6ʕ+-,,z"~[4iҭ[=z~SE'jӦMB}O={_QQ1`3grP`` ڣ١RB Z# SE QΆ#?O>T堠 KKK J~CzzΝ;i*RM~iiiׯO?~x5?!VZv}y{{T$Uۗ2z蠠 ܵGC'""!J~={j]z!4}tBǎ#>Bh̘14>iҤ'OP ٶmB?D566R"EN<9o w}ɓ'4K+ ~SL<7Ay :tڴi}{l=pW H{:Ak˖-FFF(GaU}ut&LPWWיLPBG0hĈlh @#Fq9pAP(`@+,  !4bĈlr!hBhذa/.h?Bݺultq* ~?>uԼyvE"B\/;;w!B"ܹ׭[wersbmm CAS]]}ĉUV-\pEEE+oo7oB'888,]\D.*w9w\P}!tx{{CO1k׮ms&rti̡O.eB&&&xlUп\@dR/!!ؘ'&&у|3ɵI1+,,l~~~ X?+nnn2X7^_ĉ97&+FLJJd /abbafagpLQ$tɒ@{۶mV9-|VVV X[ٳ?#|7|?;kggBUX___ 7l_-Z: By|>fff^=**ի ܲe ) WX8::>| +W?ݻ˗?EM2ŋxxt0 { ?׏9|pZZڀ` xwqM]Ož*ą nQjZV՟uઢb*ֽ D@PCe>O BHn%7~3p9۷dW :.zѐ!C<<<|pSN]N7 t? "['&BHKK'AHOH!Xv@>>wss=rH aڵׯ_"CSlmmLgqQ\pB ,,,%%@ tWQQ葩SZ[[Bb#QrJt ߄SԄ֕ëg"Ə8n8P\\ bs!p3k֬KSSSM&fIII}!oW_}%Zs,ͱ0f777,++CIT|m;FݸqIGGGfǏ/m#HAu&cٲe?2:!===GfeݺuFFFx "!ϟ5k0L1qD\JNgʔ)Ǐ2:>}Bb?bKTWW󞐑`0mBXTT$G,^^^b4i$\N 7A e111="&á, /{X!˥hIMM4h$''[ZZJKPGGx ]Y`A]]ŋ{ NB>m۷8ڵk{űBܝ?~̙ⷓ$VH!&t`ԩ! 6˗/>}3fMihh?~BөD\ŋ?SUUCEzt 7+ .LNN.--~ Э[(D_ߟdU$rssutt,--l'--B}?OEzt 7SӧO/bbbzNۛvd@.ݷoϟpMMM\.~YfyF䪸ȳvڟ~Iv.\,~;&:z~s`cccRRRhnwo.֬Ycjjf|lNCC7|ӷo˗׷}ã-OMMݺ"rU\ɄUnnoӦMC19{ؙ&ࢨB$'' [md.tԾ'O .D(.@:{]...s:@7oիم|…Za XǏ| .dd2ҦLBv!@7ܹs<BGܹsdN:B={͛7kjj}&ILS{ IDATL166& f͚f\3!t͛7 HH>}Ǝ+(++{1ٳg_~kX:"11QUUU{?͞=b]vM tEbbمBp8III'O& f͚u zA(NI򪯯hdddkkKv!@ΙXZZ BG!ܼysr<'NLNNW[[ V&Lw!t_jj*Ñ0aB(55'@ȿ7o9wd#ցБpl$t*%%HBIIIqqޡŋ#G]^x ,&Lm۶W^v|бBHKKΎ*Bիd" P _`` %HjzzzC9>>Ϗ8m׮]6mz6ٵ(..B/B(>>B䄫Ç;>tBh,K~3+**222ğ=z46VG:!Իwooo?Bpvee対BqppxQCCCLJ t+444???//BtI&ijj]P8l6;??C:>dȐ( MmmmJJ [RXXX=|C:ZdӧG%&&Xӧ]PPvvv=B_rم̙3d]AAA:՝3gNdNyy /^Lv!@q 2oi'44K}2ɓdmmmmyy9rv\\\ &맓\cTUUɮ(. C[xq\\ܧO.DtϞ=[d مf``QRR·B߼yTLN1bСC.(4 2p@uuugϞ]`م PZZʷBd"Gl dqYYBN=zĈx:e݋/իٵ !t `pi_YYwߑ]!ddd;: 鱱d\.t$g``P__v!N455Ν{ak֬!KOO!TSSv!N-[VTTt ֮]GEv!N~ɍ7VZEv! BBCCϞ=[UUEv!۰aȑ#a UB|@ﯦ&.\a PSSSۅ:9rDO'oٲӓBhGYY!v!N7BCC矴4 Rnnŋ7nHv!hT*Bn :YO'o޼|҉NCXhh{ ă\~z s,F]=___MM͘ իlZfcgvx t6o޼(Cv-;w.55u߾} Zv`E.ҥK_xqm Wss?8w\GGGksu+͘1ct+**~7 K!mm !tz…CۓǏ7o 366&u:C@GWWWJN'o޼YUU.Z)##G~:ׯ: Ё+хz*992.]joo|rr[:h{:wΜ9sRiWVVfhhwKYȨРo>}СC/_L&ԬZjɒ%0R׭[Phh(m455IO.-gggUUU;;ϟ?ST˦&b&_lmؖ{فCv…Ç'@yi.PX,VBBرc̚>QnF}m߾wiĈ `٭@իW&&&| !t뛑rY,ߣY|aN͛7} N "S\\laaBG(ÇWRR7Iy޽X8@Q00E?}dnnηB9tдi:KJJ6lO?YYYItCƆo!B2d5)%ɓ鈈J 6ܑ]dڵk%5|%vSh4Zpp0Yȓϟ+++9ѩ]vظcH4tbbbܹpf.ad#Omll:@@>}455ێFR%:>|Xf͊+ &M(8ѣGΔQTGG[|(((:th:=cnn~M:λɒFI.t.\e BOB^ :.1xTr{:QQQ׮];y򤺺$?|𡬬ֶC:#}}l6=={8qHڜ9st:N={6ٵȉѣGw]\x1"czzz&M¥ALAAA5|p92#f[dooob6rӧ-q{O>Ji;Kw||-&5JB.ۣe޼ys]9|}}.g؋'Iy#ĉmfdd0n.8::u55)TjTTANNN~~~kk+I|R 77[!DFF}!dllZlB())H%Ν;Ӛ:=vر۷oR(-xDX<<>BHjjqRSS6C4pNйyҤI&R+0._u tl}||F{㰧wB =@;o߾W^mcc#!t\R__?""BB_/^oܸ!Dz€=~~~SLV t^SSsNn!;wX=*--o-Z-mAlvPP޽{ ^mۖ%VB=Zvv͛7n8bb*//'l:(iӦ;wNI3-pNիwjii]O:u9+++7 W(ׯ^:""b֬YoB`0fϞ|r# Bk.j@QN6166J%wB3f+..NYYJ򯦦fʔ)YYYzzzĉkkk322$=l0 tgXԤ]B:ȱZOO߾}[JdUuu)SJKKoݺ5h r!//A o=z_]?JffСCH:)Dž Lzybrb׮]gϞ1cƹs.KpԴ`ݻw\r˗/9B7Jnni j̙>LHH `*AEѪ\n6449lȞ?>k֬ʛ7o]PPP&&&cƌt*ڿ+W=ZYY9''GVAE$CҀb\rƌYYY2qO{:4mΜ9#ooCEFFFEE]Q@ť7ydv!F|TVVv) EGt:?dWlC\]])q!??V???kAEEEnnn+W OOO "AƎ?vXhiiYvy dWOAECh4󟖖R5jԁ<9x`R P\L&sK,qqqqqqYdL&ae455mڴՕNgff88m9so rÇڪaaa/_Ė|2,,LUUU[[;<<Ǐի{immP,o߾ TWWpuuuMMͰoJS԰0Mz@E eee==*ϯSVV z9^0p:>jԨ\:@=}4((NFFF nmmmdd!N z\zuڑ r<BȳӧSTcczک466RӧOm, !+*:@>eddL8!4hРflnn8qbff+//_ͥKƌ1bĥKl6x>1c\tIoޫW/CCØ܋E:@N옘aÆ!/]p$9s%GGGаa6pbbbLLLo.25&&!4}tA vgkkNMMuppPRR 22dFFFQ(ӧ߹sJ )#B0a;}t\m Wcc;V^˗/crHzʪ'\*ھxӧOJJJ!!!dWį8$$DIII__?""ӧOdW$] t(// RSSkaJ:aݸԴɮHZ@͛0 J+VeeeDDq ՞={uիWDDćȮH|ݸ={FvEdRɓ'شX:yűc _O555KK dggPER}||Sލ/_Μ9SGGb BHlTDnޞ7k566`k}d~?۷/J믿D655EEEƕ#Nk=ջQUUe``6d###%W"eo++\itVbb"BhРA◄]S3fLrrm ڰa˱-,,$X@ t).X܌9Sx6^K.1Dk0_-ǏB+ndb'N>|3\OOO 3f[V)..F8d:Jrvƌ#F8qk?MF@rX'Nϟ? #++S:'ꮯOJJ;wmBxzzfee1 cc۟8q7ٱ5Fa-B(88XkWX)SSSTFF.Zm 4ɓ' idd$ķ}ƍMMM%'BD7==-:\.h޽$MKK۷/B(<<ߖڒ7 VTTF:tH+B3txܹ9r$~ud؞3|hjj5j֭[\'ܹs!S @IIIXXJ>}"""%-B!_iTWWGDDGEE%,,D[ .q8nׯ_GHhc)--m+L[+t222B666_eeeٸJKKqOѣG---?rlѣG &`߿UQQ y5^-766&%%ukZL&355[˗,2>>~ %..\ׯCBBTTTtuu#""޿c|z7222Κ*ݶsssB/^YTT$~.:;;uJAIDAT{xxN722NKK*LQQ6W޽oNFW_J\vPAA6@^ú&ݻww=sY~D*څϟBׯ_'0 SؽQ2dF 8'_7. |yPP1O`B֭[NNN!Ǐ X622NURaa!a 22G'{ ݂x]r7n\VV׷ƕ'N1X)ccH)::`kk?\ |BXg#G&%%֍!4qD3'33}a``%1a]LL –!&L`0$T"UV }777nPb2tnn iMMM۷on#O:pԩƥ(ܮ0aĺ.[VTTZjd;d PX`ɓ' (.0te˖M2ٳg% 2݄Nccٳg ('''??!C|JvQLݏ_xj<)++ q8u-[TUU\~ӧE%ll;;aÆ:uJ5YrϞ=q '( =GѶlLBBvc1${:iӦh4\ZZ333}||6l؀ zvsO<9zR&M;v,NȈ=ճб^tMjjj$TNϟ?5jTuuuRRRjj E"""8κu$Q B^ 2dH~~3gx N޽|...f!. GD]yϞ=JJJwf Z[[?|@vE@>xxӧO󵴴B@$lm۶-]t͚5d P(Ǐ7668Xlٲɓ'?{%'}ݻwѣG]WA0ovvv/^Ɂ)v߾}{BB. UTTܻw/..pc1 ^ -Zɓ'&&&x5 ۷8p@[[{pc1ߧͅˮ䪫۵k9ڵkWXAvQ o \\\ L@]v555}aaaz"(s ^|8v3g"a7_eeUV^OvQ333s]xqǎ7:r-[6ugϞm߾H'Loׯ_Dd'''???[[[ltKuʕ_9s222$ `0\]]'M}x H? N/}᯾/˓VÇ'MNR FRRѣ. H0th4ɓ']\\BG$i9V\\;r>$%%]= A)++߃ >> i*B֭Qmɟ>}MC9sFszc͛6m搨EE$DztDMa|رfZr]=%iW>aaa؁^uuʁȮU<|L0̙3dW$Azzz!~Ǐ]BЉ FX!O:,`xl0l3g͛0`@nnnNN-33֭[FFF?=Q>'))iFFF!*l2;;***ƍ۽{7Bĉd@gؤ$]vU1&O.c dcO[IIIuuumw#G]tА!C.I8qbڴimblv-XNRIݻwB| م= &`00LPSSSfffۅ=ںuߍ9o޼YlYUUB1%%{=f9''gΜ9CmzKKKVVT1-,,fϞիW,\1nCɝqcW/ϟ?>566v[0w$wUƷ~>rlDIdй#| bNطo߾}.I@.A P:BA P:BA P:BA P:B9r/a@[EBBBhh(YHU (R20@A9 t B@>82̟IENDB`tins-1.32.1/examples/multiply.reg0000644000004100000410000000167614353307475017024 0ustar www-datawww-data# vim: set filetype=ruby: # Multiplication: C = A * B, A >= 0 and B >= 0 register.A = 3 register.B = 7 # Save A in T label(SaveA) { decrement A, MoveS1, IncT } label(IncT) { increment T, IncS1 } label(IncS1) { increment S, SaveA } label(MoveS1) { decrement S, SaveB, IncA1 } label(IncA1) { increment A, MoveS1 } # Save B in U label(SaveB) { decrement B, MoveS2, IncU } label(IncU) { increment U, IncS2 } label(IncS2) { increment S, SaveB } label(MoveS2) { decrement S, Mul, IncB1 } label(IncB1) { increment B, MoveS2 } # Multiply A * B label(Mul) { decrement A, MoveT, DecB } # Add B to C label(DecB) { decrement B, MoveU, IncC } label(IncC) { increment C, DecB } # Move U back to B label(MoveU) { decrement U, SaveB, IncB2 } label(IncB2) { increment B, MoveU } # Move T back to A label(MoveT) { decrement T, ClearU, IncA2 } label(IncA2) { increment A, MoveT } # Clear U label(ClearU) { decrement U, Stop, ClearU } # Stop label(Stop) { halt } tins-1.32.1/examples/mail.rb0000755000004100000410000000250514353307475015710 0ustar www-datawww-data#!/usr/bin/env ruby require 'tins' require 'net/smtp' require 'time' class Mail extend Tins::DSLAccessor include Tins::InstanceExec include Tins::MethodMissingDelegator::DelegatorModule include Tins::BlockSelf def initialize(&block) super block_self(&block) instance_exec(&block) end dsl_accessor :mail_server, ENV['MAILSERVER'] || 'mail' dsl_accessor :body if ENV['USER'] dsl_accessor :from, ENV['USER'] + '@' + (ENV['MAILSERVER'] || 'mail') else dsl_accessor :from, 'joe@doe.com' end dsl_accessor :to, 'flori@ping.de' dsl_accessor :subject, 'Test Email' dsl_accessor :date do Time.now.rfc2822 end def message_id key = [ ENV['HOSTNAME'] || 'localhost', $$ , Time.now ].join (::Digest::MD5.new << key).to_s end def msg [ "From: #{from}", "To: #{to}", "Subject: #{subject}", "Date: #{date}", "Message-Id: <#{message_id}@#{mail_server}>", '', body ] * "\n" end def send ::Net::SMTP.start(mail_server, 25) do |smtp| smtp.send_message msg, from, to end end end def mail(&block) Mail.new(&block) end def prompt STDOUT.print "Send to? " STDOUT.flush STDIN.gets.strip end m = mail do subject subject + ': Hi!' if rcpt = prompt to rcpt end body "Hello, world!\n" end m.send tins-1.32.1/examples/length_difference.png0000644000004100000410000011167414353307475020607 0ustar www-datawww-dataPNG  IHDR|4*bKGD IDATxw\3[MJ56JQQ * +ƨk&A7YM#1Xbcl[ (D myܽHٝ3|{YgyfBP ` w`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA .\x5U< t[l]B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B(B.]k.)))ѣm~,Y28UVK&9::2_.Mjj ˝5ksRPPuV~=H8:B0dRy<ޜ9sp+//۷o7₱*0DFFr\A 0G@̘1C.+p8X`322p8666`TDD A:Q!P(t `TnFI ]B0mΜ9 bݺu] @7} H&<~x `۶m;xzBB(p0܅@O˵/'AKo{:FA`Q:FA`Q:FA`Q:FA(SPP}3guUěCBBN>M_Pm%@ɓ'{I_U[[̗}=x>ضm=E `@ (Ya\4rСC{#c@&@zB t/++C 06:uWZeooqFܵA&uk,}}CY@@Q(K,A.BKLLˉ'֯_@ .;v "::֭[ԃxↆ3f.P BP.%%jhhx"3g/ݻ7k֬ VM;otl+ (cddݷmk``zԨQ&M:z(y5bĈ#G9rUC:2ꫂr9eQ "FMpy`Q:FA`Q:FA`Q:FA`Q:FA`端ںuk_P455|jsss_4k/ʕ+=zԥܽ{cƌr*̙3*׭[׭[7B(!!a{9sj-[nŊpJ_W{y.]r 233 xc( t@UWW2.%%Sݓ'O\;w޶G 2]##""$ɁI'O d2蚯Ӈѣ:V?N]p5klذaСj6ɯe2۷?v@=YyyyC 6mږ-[o- \.o߾7n܀;;ZBtJmm lM*444'Ǝf t/^=zTAݹsux/BA耎[ vvv4xORiVVVrr2%:p>,&&& 6/_y<ի: `'SPP0x]vQج[~~oVV)<`VuuuA\xАfuP(|>AMMM䇐yxx$%%Qx86x geeQzzz...'Oζiz:m%KN<9zhZt)SH$ZXamHKKDN@ P(th,,,lҤI?8P(D2p,: ӦMܹs'33ufnncn$7|'411a:vܹiӦ#Gxzz2y\@; %++룏>ZjդI>P(+BŋSN1bė_~ѡS td|>2ccc# ttWUUɓ vZܵ '''%###ܾ*Bz:: `An_uyܵ @ ]`tt}ƍ߾*0TGw@蜼ٳgϟ?kPX\\,qh[jkkLҧOw-oeee ! "22ŋ -}YWXBG[رcj* Cxz+N>vZܵP=-$J}~A~AA̙3#"">c`hϧ]|ygʔ)Bp͸Kk:Z~xR4))O>/))|* /BGH$#GHRPSSSIIIII'|B>b3@PTTP(Ytd2LwEGGd2uH ={ w!^:fmvWWW3_R'X:BG;v\.?+$O͵V?nN Yf}gY<z:Zn$kݻw r{}aÆa`.xYjjjk+>;w?ql=Am6wwwUu@ ~:*=C{x;w}ւUl̬[np[Gk)@' 8k?nkk<66UKEEEmmszںuj4jAٚU() thaCCׯ5 !iӦNhזFFFAAAoUl 6b:;r}||lmmcccB4z5Qڷ O͵v9n8k777B F t6BGAnРA\.!rkV߸q#5Qڷ) ) v- .\iii|?tМ"|]"r9 J:Ϗݳg /W(K,AR]e|$r| \ai%444\2 @Fbbb\\\N8~z k%o!diiijj CD"ʕ+B BFwADtt[MKV:Lضmٳg7 rɑ,* ZxqCCÌ3ꨭSMM thx\ \ f͚6_pE3g466^dݻwo֬Ys"6mv,奭 th7uT2,8Ό3 6_k``3jԨ0"ȑ#NNNTey]Kyi+˜vxRedPP\.W,9̺5@PZZ*Jyyw!J:`,^OOnh^z:ZB >:੹} tWo[Wh"j@"<w!2:?}tB LLLpV>dҽ/RYYzjZ҂rrvrppr?@TZZ: >Ro,a9\.KIGKA0- e2X,Rf!h:y{{7 ~qY`a8p`@7K`)/MᆱG~p<=='M$ 5Ea Nޒ4@ (** *ߟLhxx84P(lhhx)B t0puuEzj\%aZvvvvvvPPB2""wEޞýdÜc\r!m``. r!t4N:XVVo߾}IRБ#GOixj th$Jwݷo߱cǚݼy3<<<<<޽{iiicƌ۷ݻO5-ׯ_>wܞ={'%%X+gذaIII/^ٳܹsׯ____f 5P6&&G\.7""͛y͛7#""\n=bbbjkkSرw@E:VVV|>?***??-EEE|+++X\YYIGZ 55!s܅U@PL$DǏǏE"H$*//Nz*B* tR\\,bӧOjӧbX$Sղhllr]P>>wdKc@ ]2VbTeOO9s8;;edd5 w]m5jԥKҜ̙e]`i0wYD" B BCC_~zhh(AB066V"ஈFuuuA=zw! t Z,x[nuGm۶mƌU i]t-rX,iQ;ҼܹC߁lmmׯ_O_&: S"H S$//Юv%ə3gW|hΝ666WB/ƕwUUUEGG#|||;СC>9aH$ߦjW_uiD"###rWYY vh͚5r\Pz !dmmM߱O>uT4)**׷Ϟ=eBԢgϞb rOQQ%ͶI٥z;g}6p@4ѭɉݻwcT?lذ.!jFUWWXZZ oi̙\v?leeE!t%t9}ӧO˔WHNrppp8׮] b䛊hhh W^>ΥK pwwB˫<<55!'P۸ҝ;wB> tə0aA={_>tjjjrrr֯_okkkaaNCSWWyfr\ĉ)_7c!jUA?~M9t>3CfHՍ/R~OmΟ?occJ6׽{͛7>6OoA``2+!t}P( $ jANӧ6`i"mrV+W¼4bVdvv6ݔ#w LKK# |.˗B-`,Ŝ4򎲋Kll,x$Irrr~~~mܹs RӧO<(ؿ?*XqZZ+ WW)S<|077XA,_חt(tH7n &9;;S8+4 |)SΟ?OIaXgggr7l onҥFFFܴiL&@.MvlsCsNDDdz/_]]^|)ɹZѣA.t@$EGGWTTஈJfff"wEԻqB6,::'ODGGDD95::ɓ'+˗/BO]<\,w֍a*77wE%w֭X,օwͷlق :oxyoy}uֽ{ȹvvv3#W]mSSe˖gϞӧτ pr}={~]l)BhfPK IDAT6/[,??Ν>D(Yݵ֬Y# k%$$丸 2d˖-B8;;COG(%i\S媵S^^.LMM [OJbDDDh]2vعst>}*̌:X$O7-,,|||=zDE?1b*@gAPehhHΥxa^x!>|د_ݻ:u5ط~₻ Y:8qA+W#Gܻwݽ{744WMM {,۷oϗJ CcǾ{ >..ɉʕ+/dff999ũvj\\u:ud@!ݿ G*"H6l@Fϔ)SLp7lؠഴ4;;;77[nٔ*--Eѱ3,Ya{ݻ)kӧ#F044ܹs'Umj\n``g܅NQ]LLL֮]p1MMM(ZNf'ww wS`p v܉?>x111{GY^^px\s C%\iӦH ,̘1#+++55K X@h*?~ѣG˖-(ěZ^zeff~}lA tnܸq /&$$|WW9sfmm-P($.t BkZmo۷E"B4:hР㮈^ӧ С͛===Ǎyw}}}> B:Ԩܽ{EضçMrJL"Z888| tc7o<܅A__?..n׮]6l=zgpWD=.=:mKLiӦ9syYǏ4ʕ+ˡ<5:HJJ*..^t)B:s޽{nݺw9 46l0fwww܅t{'OFFFᮈ2:uٳgQ"'&&;vlذaZ;:ڴiS^>܅t\"J tiP@(~w!:jسgϒ%K3233'N8nܸ5kr6:jٶmޜ9sp";vl޼o d\5 tT'J7op&.?=͛7oԨQ ^HHHfffEEŠA]4, tTӽ{~G ˗4hA@PUUU]]Ul۶$22w!4255=xڵk͚5K#$AtYSSw-"bٲe)))gΜ]QA:,eӧOIygeee 0ȑ#i a9.۸qĉɞptt %NlܸqРAÇ]{EEE߼yԜ t:VZZ;T6hР,r*z:,ӱ8KK3f.DXYYZ~B t:P__믿.X@__w-=zFz z : BZhB4ĉ\B.?x%&- Eqq1Bxeiiу޷o9vSN]  drKy)X = &333AGedd.JX>O.?A̶ṉ@WAO r!P(*++wMW_}'UeAf:on.MMM ӣG4hPbb"4Z``rG}86yCeeeJRЍ72 .,Zhʔ)t/?` AIIIDf~ƍ'LK`:\.f4k֬ Z3.yCee%τ$$$t~wUUU 0`…/d2YiizeZ@輡kX͛CBBԣ5k,X@B1c͛7lr)':wm濺m;vС/"99Y.s89s樼Ja'] +W̟??>>5˗/ϧ83^n;vlFFF]]kL/_\zjm\XXι`ȼgώ5 !dooOP(ܼys]]̙rB\.722R.cV\vM__A TkpРANNNkNT*߿?B/99YPD"ݻ⊊ BnCCuׯ===[MxoCn nfaaH$222211D!___D`s\ru\V@Ǵ6t$Ill@ "44gbAfffٌ >vZP\GEEQ@0tb Nj}v'_X]]b KKK>Ckt??? Z_aYm_S\t5*t***bq D"ѣGThױ'888++:AkcǎWp87onp5NiiH$211122Dj6NDppK(tqqqAx<q##bkͧSTToaa!={Fa㍍B( 11Arss>}WX>εй~DDϷ}MdlODä{-Y\ѱGp5FNVVVpp0qpp}53MKK{BJW5?}k-as%rH{||<{iiiBFkpƄNbbb@@Bw9xL&[ύ7"""8@ s:r>>>'&&b6w툈gcc#pW\9_~#G<="EGGԞsS:... 6{IttrjOii)4kĮ!'8;;s܈7nந˞?"E}}=NYl /_bkkkr͝;wBAAAHHۺu:?dCCCwwsfffv ҫWbccmmmɩ=W6G 84&Ċh333rMAA <ֶ)66H$gΜ!_˺;wp8]zHGGGrjիWUn/^ %k\ӧB%%%I4O},,,._LGiii#GDDa&Mj~㣏>bx"h= Ça:IOO'=<<D_®~Q+wޥH9 X*dEEE۷o'ׅ@mܸ;mh: "44t޽zpD{g&u֭ 333SByjjjrrr֯_okkkaaNCoHKK;v,yC–'Nzw(lm\ws}U')Cf{ B.zW\INTH$:tPUUH$IR [=B(??f纫(9+WoZv [^^^TTdz􍎍0arŋm?ZU9fС4k@ 6n}k1W\AAH$244455DԶuVwwwrL&ۺuw_T#z.L.tO8JNNFZCZs!1]ӧObH$Fzz^kΝ;G@*>}>J理Bbcc{IoygXXXAAjkk8P\3pi9S[nzzzo-#8NO_PPPm5SL9)уxMZnmʕzzzz/n sNjjjbcc8Nhh(,qVVV|>?***//wEJs>..ɉ)d_*//D"Us l됧'B( %%wEj)..Dbӧ+b8:-C" 8w:r~X,ң\Zg+tHr<11!)ݽ{744HAl %C}cU233i5NNNqqq+oee%++++DN!kOMs[aC ȩ=eee | -B06T<~4.ϵƥ)4,td2ٚ5k\nhhh^^X,677'TCP($"44r|̘1\.Rƅ\t ]ISRR2|p##xcbb,--ɩ=ž<׀*4GGG@¿cԞANLQNݻ:q8ղ ;׀ _~?BBo=ڵkM*Oټys;|>ۻTAW1pX: B"̘1P5K95..{777wh &#055򲳳!k\? @n\} 2___ 'NPٳgɭlll >7odϭ#wSSSrb1 g\ۓ䧟~]`Ydgg BWW۷ow==QFڵA4IIIApܐ􂃃 Eff%Ks=t˗)tN8ajj:rH5o⴯ !t!:_jՐ!C?YYY={tssx͚5kĉ4yk֬?~9sOKKK$HBt47dffZYY5322 q\nnnyyyHҨ/~ڸqM122(-ڦ,X 44R;ѣGL} Ѵ̨3gNbbݻg͚ di鴃C {nח9::EzjرɧOf&q!M>̙3/^/**RrssCvBѣG.] dX.p8~~~W^U155]:Çd/^$'0oOx…ݻc%ڭ:a۷o>G  211?"###""6oތ؀w=z۱c,,,>:BH"p\Ϗ[xqEE"ziU:FC#Gӧϱcp5jkk Mk֬qqq?~~~mY.؀+W>rGlqIO~mBddyxxxUU \-Nzo ۫Wȉr=+WÇg,qPJ$BhҤI'O<{qjjjpZߺ"xj=nܸ߿yZv{wSSSܹ{=w9=trrrF흘Ȇ,R8p`JJJiiiHHׯq8NϞ=#G;))%oyyԿ3g?|=h O=֖=X|y;拉=﨣͉ ;B&88:ǔ͗WJgϞ}رc:Zpy-^\\Ķg,RHMMχܡϫqh ?0--ɓt_^)?ətݻw:tLJէWJ?vؕ+WfϞ OQB(x<(?OmTH$! :رc'NOqע |3iW\7oއ~((lZ! >;v̚5k<#{:/^ܰaƍY8mJiƌs΍zZ4l SSS1eʔHj v\^)ϮMMMk00#C>H$ Mk.HѸk0X:g\\ƍY>*ZlzEGG-[;v w-M*vXt9tϟ?m4xFނD"aT:uY.\˹wl QCocЉW矹\.ٲUXc?ӆ lmmi*Z bŊ]ׯ_ojj_9Nn|IZlϦv5jԨSN6 w9TTTobbsNrhУXExۼϞ=v˥& ZXXr \P(R)B(11q„ Xk󓒒޽˶%bYq999Hnp5_Sօ˫ǏlڴIS!dllCUhhرc,X@v@ |=S#H>ɉ(ЧO?7nmyyy7n+Vh\ccA::D"Yr%dԩzzz,XA7:mҥk֬] -_w:8t tޝ0q?dqCիW#bbbpF+Wl `w%mllo׺uqF_T~8NHHtH=Tw͙3G& K*j-/^_.);;pig޽{y<ޣG@8qB!am˖-qPWWףGxSNHtYnԩS{Ic1#z-XPb޼y={;;m200ЁȌj'222BE &L@Akaȯ_ZZ6'oE_|||?M2EP{**sε]7!̴QMMц hͼ^z^VVt¢w!׿L?[om>|\?˗3OM]]3x8coҥ}opBܵtك|}}.b֭]6o {͇3744, 3fl޼YC!}%=/^3\ ŋoݺz[$%%qܐt)%:#FuӢE>} 3_ -,,v؁ ̚\kFgϝ;_ms=3F;wY >.\XRR|X:.\иA\\\ƌv-CG.gff>K5V-:uTnn.BNk:>|,/Ǝk.܅2t_ׯ_?,Zqܹsڵ n'Zݻw=<\SSZNAA R3e2١Cpt#HpUDh"kkkKKŋ744t999~5W( &M 9~t-88Xwh#Gu}̙%%%+<{ !|( HMM%bȑ/_ܻwo'_)pe˖6wIɓ'¸su>!aÆfgg.x!dmm.pBRRҒ%K߯_K۷ڵk|y}}=Q8 秦8qYYYi߽Q~bo?YPPn:uyBS1]FޘxoGڿ?ΚP(Mի{S&W(4ZZ !G?(8=:Ul?!J~K~|J@@@gt$''ԔUwʕe˖9::R3rssoݺEa,'$###$$VOO{l[o.B!:Nyy9B[nd픔dddxyy}7l{C^ۛv}}}>~Sl'D$]p!33իW۶m;p@TTMOoNSSBc*^|200 %㲲R iiiiii|rЦMhUU Dr…ׯ744޽[f 4iSUYY) &M:wwUg}×/_O!j;Ŕ`[a#?LRV" Iq\/B޽{T6ʕ+-,,z"~[4iҭ[=z~SE'jӦMB}O={_QQ1`3grP`` ڣ١RB Z# SE QΆ#?O>T堠 KKK J~CzzΝ;i*RM~iiiׯO?~x5?!VZv}y{{T$Uۗ2z蠠 ܵGC'""!J~={j]z!4}tBǎ#>Bh̘14>iҤ'OP ٶmB?D566R"EN<9o w}ɓ'4K+ ~SL<7Ay :tڴi}{l=pW H{:Ak˖-FFF(GaU}ut&LPWWיLPBG0hĈlh @#Fq9pAP(`@+,  !4bĈlr!hBhذa/.h?Bݺultq* ~?>uԼyvE"B\/;;w!B"ܹ׭[wersbmm CAS]]}ĉUV-\pEEE+oo7oB'888,]\D.*w9w\P}!tx{{CO1k׮ms&rti̡O.eB&&&xlUп\@dR/!!ؘ'&&у|3ɵI1+,,l~~~ X?+nnn2X7^_ĉ97&+FLJJd /abbafagpLQ$tɒ@{۶mV9-|VVV X[ٳ?#|7|?;kggBUX___ 7l_-Z: By|>fff^=**ի ܲe ) WX8::>| +W?ݻ˗?EM2ŋxxt0 { ?׏9|pZZڀ` xwqM]Ož*ą nQjZV՟uઢb*ֽ D@PCe>O BHn%7~3p9۷dW :.zѐ!C<<<|pSN]N7 t? "['&BHKK'AHOH!Xv@>>wss=rH aڵׯ_"CSlmmLgqQ\pB ,,,%%@ tWQQ葩SZ[[Bb#QrJt ߄SԄ֕ëg"Ə8n8P\\ bs!p3k֬KSSSM&fIII}!oW_}%Zs,ͱ0f777,++CIT|m;FݸqIGGGfǏ/m#HAu&cٲe?2:!===GfeݺuFFFx "!ϟ5k0L1qD\JNgʔ)Ǐ2:>}Bb?bKTWW󞐑`0mBXTT$G,^^^b4i$\N 7A e111="&á, /{X!˥hIMM4h$''[ZZJKPGGx ]Y`A]]ŋ{ NB>m۷8ڵk{űBܝ?~̙ⷓ$VH!&t`ԩ! 6˗/>}3fMihh?~BөD\ŋ?SUUCEzt 7+ .LNN.--~ Э[(D_ߟdU$rssutt,--l'--B}?OEzt 7SӧO/bbbzNۛvd@.ݷoϟpMMM\.~YfyF䪸ȳvڟ~Iv.\,~;&:z~s`cccRRRhnwo.֬Ycjjf|lNCC7|ӷo˗׷}ã-OMMݺ"rU\ɄUnnoӦMC19{ؙ&ࢨB$'' [md.tԾ'O .D(.@:{]...s:@7oիم|…Za XǏ| .dd2ҦLBv!@7ܹs<BGܹsdN:B={͛7kjj}&ILS{ IDATL166& f͚f\3!t͛7 HH>}Ǝ+(++{1ٳg_~kX:"11QUUU{?͞=b]vM tEbbمBp8III'O& f͚u zA(NI򪯯hdddkkKv!@ΙXZZ BG!ܼysr<'NLNNW[[ V&Lw!t_jj*Ñ0aB(55'@ȿ7o9wd#ցБpl$t*%%HBIIIqqޡŋ#G]^x ,&Lm۶W^v|бBHKKΎ*Bիd" P _`` %HjzzzC9>>Ϗ8m׮]6mz6ٵ(..B/B(>>B䄫Ç;>tBh,K~3+**222ğ=z46VG:!Իwooo?Bpvee対BqppxQCCCLJ t+444???//BtI&ijj]P8l6;??C:>dȐ( MmmmJJ [RXXX=|C:ZdӧG%&&Xӧ]PPvvv=B_rم̙3d]AAA:՝3gNdNyy /^Lv!@q 2oi'44K}2ɓdmmmmyy9rv\\\ &맓\cTUUɮ(. C[xq\\ܧO.DtϞ=[d مf``QRR·B߼yTLN1bСC.(4 2p@uuugϞ]`م PZZʷBd"Gl dqYYBN=zĈx:e݋/իٵ !t `pi_YYwߑ]!ddd;: 鱱d\.t$g``P__v!N455Ν{ak֬!KOO!TSSv!N-[VTTt ֮]GEv!N~ɍ7VZEv! BBCCϞ=[UUEv!۰aȑ#a UB|@ﯦ&.\a PSSSۅ:9rDO'oٲӓBhGYY!v!N7BCC矴4 Rnnŋ7nHv!hT*Bn :YO'o޼|҉NCXhh{ ă\~z s,F]=___MM͘ իlZfcgvx t6o޼(Cv-;w.55u߾} Zv`E.ҥK_xqm Wss?8w\GGGksu+͘1ct+**~7 K!mm !tz…CۓǏ7o 366&u:C@GWWWJN'o޼YUU.Z)##G~:ׯ: Ё+хz*992.]joo|rr[:h{:wΜ9sRiWVVfhhwKYȨРo>}СC/_L&ԬZjɒ%0R׭[Phh(m455IO.-gggUUU;;ϟ?ST˦&b&_lmؖ{فCv…Ç'@yi.PX,VBBرc̚>QnF}m߾wiĈ `٭@իW&&&| !t뛑rY,ߣY|aN͛7} N "S\\laaBG(ÇWRR7Iy޽X8@Q00E?}dnnηB9tдi:KJJ6lO?YYYItCƆo!B2d5)%ɓ鈈J 6ܑ]dڵk%5|%vSh4Zpp0Yȓϟ+++9ѩ]vظcH4tbbbܹpf.ad#Omll:@@>}455ێFR%:>|Xf͊+ &M(8ѣGΔQTGG[|(((:th:=cnn~M:λɒFI.t.\e BOB^ :.1xTr{:QQQ׮];y򤺺$?|𡬬ֶC:#}}l6=={8qHڜ9st:N={6ٵȉѣGw]\x1"czzz&M¥ALAAA5|p92#f[dooob6rӧ-q{O>Ji;Kw||-&5JB.ۣe޼ys]9|}}.g؋'Iy#ĉmfdd0n.8::u55)TjTTANNN~~~kk+I|R 77[!DFF}!dllZlB())H%Ν;Ӛ:=vر۷oR(-xDX<<>BHjjqRSS6C4pNйyҤI&R+0._u tl}||F{㰧wB =@;o߾W^mcc#!t\R__?""BB_/^oܸ!Dz€=~~~SLV t^SSsNn!;wX=*--o-Z-mAlvPP޽{ ^mۖ%VB=Zvv͛7n8bb*//'l:(iӦ;wNI3-pNիwjii]O:u9+++7 W(ׯ^:""b֬YoB`0fϞ|r# Bk.j@QN6166J%wB3f+..NYYJ򯦦fʔ)YYYzzzĉkkk322$=l0 tgXԤ]B:ȱZOO߾}[JdUuu)SJKKoݺ5h r!//A o=z_]?JffСCH:)Dž Lzybrb׮]gϞ1cƹs.KpԴ`ݻw\r˗/9B7Jnni j̙>LHH `*AEѪ\n6449lȞ?>k֬ʛ7o]PPP&&&cƌt*ڿ+W=ZYY9''GVAE$CҀb\rƌYYY2qO{:4mΜ9#ooCEFFFEE]Q@ť7ydv!F|TVVv) EGt:?dWlC\]])q!??V???kAEEEnnn+W OOO "AƎ?vXhiiYvy dWOAECh4󟖖R5jԁ<9x`R P\L&sK,qqqqqqYdL&ae455mڴՕNgff88m9so rÇڪaaa/_Ė|2,,LUUU[[;<<Ǐի{immP,o߾ TWWpuuuMMͰoJS԰0Mz@E eee==*ϯSVV z9^0p:>jԨ\:@=}4((NFFF nmmmdd!N z\zuڑ r<BȳӧSTcczک466RӧOm, !+*:@>eddL8!4hРflnn8qbff+//_ͥKƌ1bĥKl6x>1c\tIoޫW/CCØ܋E:@N옘aÆ!/]p$9s%GGGаa6pbbbLLLo.25&&!4}tA vgkkNMMuppPRR 22dFFFQ(ӧ߹sJ )#B0a;}t\m Wcc;V^˗/crHzʪ'\*ھxӧOJJJ!!!dWį8$$DIII__?""ӧOdW$] t(// RSSkaJ:aݸԴɮHZ@͛0 J+VeeeDDq ՞={uիWDDćȮH|ݸ={FvEdRɓ'شX:yűc _O555KK dggPER}||Sލ/_Μ9SGGb BHlTDnޞ7k566`k}d~?۷/J믿D655EEEƕ#Nk=ջQUUe``6d###%W"eo++\itVbb"BhРA◄]S3fLrrm ڰa˱-,,$X@ t).X܌9Sx6^K.1Dk0_-ǏB+ndb'N>|3\OOO 3f[V)..F8d:Jrvƌ#F8qk?MF@rX'Nϟ? #++S:'ꮯOJJ;wmBxzzfee1 cc۟8q7ٱ5Fa-B(88XkWX)SSSTFF.Zm 4ɓ' idd$ķ}ƍMMM%'BD7==-:\.h޽$MKK۷/B(<<ߖڒ7 VTTF:tH+B3txܹ9r$~ud؞3|hjj5j֭[\'ܹs!S @IIIXXJ>}"""%-B!_iTWWGDDGEE%,,D[ .q8nׯ_GHhc)--m+L[+t222B666_eeeٸJKKqOѣG---?rlѣG &`߿UQQ y5^-766&%%ukZL&355[˗,2>>~ %..\ׯCBBTTTtuu#""޿c|z7222Κ*ݶsssB/^YTT$~.:;;uJAIDAT{xxN722NKK*LQQ6W޽oNFW_J\vPAA6@^ú&ݻww=sY~D*څϟBׯ_'0 SؽQ2dF 8'_7. |yPP1O`B֭[NNN!Ǐ X622NURaa!a 22G'{ ݂x]r7n\VV׷ƕ'N1X)ccH)::`kk?\ |BXg#G&%%֍!4qD3'33}a``%1a]LL –!&L`0$T"UV }777nPb2tnn iMMM۷on#O:pԩƥ(ܮ0aĺ.[VTTZjd;d PX`ɓ' (.0te˖M2ٳg% 2݄Nccٳg ('''??!C|JvQLݏ_xj<)++ q8u-[TUU\~ӧE%ll;;aÆ:uJ5YrϞ=q '( =GѶlLBBvc1${:iӦh4\ZZ333}||6l؀ zvsO<9zR&M;v,NȈ=ճб^tMjjj$TNϟ?5jTuuuRRRjj E"""8κu$Q B^ 2dH~~3gx N޽|...f!. GD]yϞ=JJJwf Z[[?|@vE@>xxӧO󵴴B@$lm۶-]t͚5d P(Ǐ7668Xlٲɓ'?{%'}ݻwѣG]WA0ovvv/^Ɂ)v߾}{BB. UTTܻw/..pc1 ^ -Zɓ'&&&x5 ۷8p@[[{pc1ߧͅˮ䪫۵k9ڵkWXAvQ o \\\ L@]v555}aaaz"(s ^|8v3g"a7_eeUV^OvQ333s]xqǎ7:r-[6ugϞm߾H'Loׯ_Dd'''???[[[ltKuʕ_9s222$ `0\]]'M}x H? N/}᯾/˓VÇ'MNR FRRѣ. H0th4ɓ']\\BG$i9V\\;r>$%%]= A)++߃ >> i*B֭Qmɟ>}MC9sFszc͛6m搨EE$DztDMa|رfZr]=%iW>aaa؁^uuʁȮU<|L0̙3dW$Azzz!~Ǐ]BЉ FX!O:,`xl0l3g͛0`@nnnNN-33֭[FFF?=Q>'))iFFF!*l2;;***ƍ۽{7Bĉd@gؤ$]vU1&O.c dcO[IIIuuumw#G]tА!C.I8qbڴimblv-XNRIݻwB| م= &`00LPSSSfffۅ=ںuߍ9o޼YlYUUB1%%{=f9''gΜ9CmzKKKVVT1-,,fϞիW,\1nCɝqcW/ϟ?>566v[0w$wUƷ~>rlDIdй#| bNطo߾}.I@.A P:BA P:BA P:BA P:B9r/a@[EBBBhh(YHU (R20@A9 t B@>82̟IENDB`tins-1.32.1/examples/bb3.stm0000644000004100000410000000107214353307475015627 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with an empty tape # $ turing.rb bb3.stm '' # Busy Beaver: 3-state, 2-symbol # state A 1. cond if: 'B', then: 2, else: 4 2. write symbol: '1', goto: 3 3. right goto: 6 4. write symbol: '1', goto: 5 5. right goto: 16 # state B 6. cond if: 'B', then: 7, else: 9 7. write symbol: 'B', goto: 8 8. right goto: 11 9. write symbol: '1', goto: 10 10. right goto: 6 # state C 11. cond if: 'B', then: 12, else: 14 12. write symbol: '1', goto: 13 13. left goto: 11 14. write symbol: '1', goto: 15 15. left goto: 1 # halt 16. halt tins-1.32.1/examples/concatenate_compare.mtm0000644000004100000410000000175614353307475021156 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with four binary numbers on the tape: # $ turing.rb concatenate_compare.mtm 110 1 11 01 1. right 1, goto: 2 2. cond 1, if: 'B', then: 3, else: 1 3. right 2, goto: 4 4. cond 2, if: '0', then: 7, else: 5 5. cond 2, if: '1', then: 6, else: 9 6. write 1, symbol: '1', goto: 8 7. write 1, symbol: '0', goto: 8 8. right 1, goto: 3 9. right 3, goto: 10 10. cond 3, if: 'B', then: 11, else: 9 11. right 4, goto: 12 12. cond 4, if: '0', then: 14, else: 13 13. cond 4, if: '1', then: 15, else: 17 14. write 3, symbol: '0', goto: 16 15. write 3, symbol: '1', goto: 16 16. right 3, goto: 11 17. left 3, goto: 18 18. left 1, goto: 19 19. cond 3, if: '0', then: 20, else: 22 20. cond 1, if: '0', then: 17, else: 24 21. cond 1, if: '1', then: 17, else: 24 22. cond 3, if: '1', then: 21, else: 23 23. cond 1, if: 'B', then: 25, else: 24 24. write 0, symbol: '0', goto: 26 25. write 0, symbol: '1', goto: 26 26. right 0, goto: 27 27. halt tins-1.32.1/examples/ones_difference.stm0000644000004100000410000000121714353307475020300 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with two strings of ones on the tape: # $ turing.rb ones_difference.stm 1111 11 1. right goto: 2 2. cond if: '1', then: 1, else: 3 3. right goto: 4 4. cond if: '1', then: 5, else: 17 5. right goto: 6 6. cond if: '1', then: 5, else: 7 7. left goto: 8 8. write symbol: 'B', goto: 9 9. left goto: 10 10. cond if: '1', then: 9, else: 11 11. left goto: 12 12. cond if: '1', then: 11, else: 13 13. right goto: 14 14. cond if: '1', then: 15, else: 16 15. write symbol: 'B', goto: 1 16. write symbol: '1', goto: 18 17. left goto: 20 18. right goto: 19 19. cond if: '1', then: 18, else: 21 20. halt 21. halt tins-1.32.1/examples/ones_difference.mtm0000644000004100000410000000051314353307475020270 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with two strings of ones on the tape: # $ turing.rb ones_difference.mtm 1111 11 0. right 1, goto: 1 1. right 2, goto: 2 2. cond 1, if: '1', then: 3, else: 4 3. cond 2, if: '1', then: 0, else: 5 4. cond 2, if: '1', then: 5, else: 7 5. write 0, symbol: '1', goto: 6 6. left 0, goto: 0 7. halt tins-1.32.1/examples/bb3.png0000644000004100000410000011167414353307475015622 0ustar www-datawww-dataPNG  IHDR|4*bKGD IDATxw\3[MJ56JQQ * +ƨk&A7YM#1Xbcl[ (D myܽHٝ3|{YgyfBP ` w`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA .\x5U< t[l]B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B(B.]k.)))ѣm~,Y28UVK&9::2_.Mjj ˝5ksRPPuV~=H8:B0dRy<ޜ9sp+//۷o7₱*0DFFr\A 0G@̘1C.+p8X`322p8666`TDD A:Q!P(t `TnFI ]B0mΜ9 bݺu] @7} H&<~x `۶m;xzBB(p0܅@O˵/'AKo{:FA`Q:FA`Q:FA`Q:FA(SPP}3guUěCBBN>M_Pm%@ɓ'{I_U[[̗}=x>ضm=E `@ (Ya\4rСC{#c@&@zB t/++C 06:uWZeooqFܵA&uk,}}CY@@Q(K,A.BKLLˉ'֯_@ .;v "::֭[ԃxↆ3f.P BP.%%jhhx"3g/ݻ7k֬ VM;otl+ (cddݷmk``zԨQ&M:z(y5bĈ#G9rUC:2ꫂr9eQ "FMpy`Q:FA`Q:FA`Q:FA`Q:FA`端ںuk_P455|jsss_4k/ʕ+=zԥܽ{cƌr*̙3*׭[׭[7B(!!a{9sj-[nŊpJ_W{y.]r 233 xc( t@UWW2.%%Sݓ'O\;w޶G 2]##""$ɁI'O d2蚯Ӈѣ:V?N]p5klذaСj6ɯe2۷?v@=YyyyC 6mږ-[o- \.o߾7n܀;;ZBtJmm lM*444'Ǝf t/^=zTAݹsux/BA耎[ vvv4xORiVVVrr2%:p>,&&& 6/_y<ի: `'SPP0x]vQج[~~oVV)<`VuuuA\xАfuP(|>AMMM䇐yxx$%%Qx86x geeQzzz...'Oζiz:m%KN<9zhZt)SH$ZXamHKKDN@ P(th,,,lҤI?8P(D2p,: ӦMܹs'33ufnncn$7|'411a:vܹiӦ#Gxzz2y\@; %++룏>ZjդI>P(+BŋSN1bė_~ѡS td|>2ccc# ttWUUɓ vZܵ '''%###ܾ*Bz:: `An_uyܵ @ ]`tt}ƍ߾*0TGw@蜼ٳgϟ?kPX\\,qh[jkkLҧOw-oeee ! "22ŋ -}YWXBG[رcj* Cxz+N>vZܵP=-$J}~A~AA̙3#"">c`hϧ]|ygʔ)Bp͸Kk:Z~xR4))O>/))|* /BGH$#GHRPSSSIIIII'|B>b3@PTTP(Ytd2LwEGGd2uH ={ w!^:fmvWWW3_R'X:BG;v\.?+$O͵V?nN Yf}gY<z:Zn$kݻw r{}aÆa`.xYjjjk+>;w?ql=Am6wwwUu@ ~:*=C{x;w}ւUl̬[np[Gk)@' 8k?nkk<66UKEEEmmszںuj4jAٚU() thaCCׯ5 !iӦNhזFFFAAAoUl 6b:;r}||lmmcccB4z5Qڷ O͵v9n8k777B F t6BGAnРA\.!rkV߸q#5Qڷ) ) v- .\iii|?tМ"|]"r9 J:Ϗݳg /W(K,AR]e|$r| \ai%444\2 @Fbbb\\\N8~z k%o!diiijj CD"ʕ+B BFwADtt[MKV:Lضmٳg7 rɑ,* ZxqCCÌ3ꨭSMM thx\ \ f͚6_pE3g466^dݻwo֬Ys"6mv,奭 th7uT2,8Ό3 6_k``3jԨ0"ȑ#NNNTey]Kyi+˜vxRedPP\.W,9̺5@PZZ*Jyyw!J:`,^OOnh^z:ZB >:੹} tWo[Wh"j@"<w!2:?}tB LLLpV>dҽ/RYYzjZ҂rrvrppr?@TZZ: >Ro,a9\.KIGKA0- e2X,Rf!h:y{{7 ~qY`a8p`@7K`)/MᆱG~p<=='M$ 5Ea Nޒ4@ (** *ߟLhxx84P(lhhx)B t0puuEzj\%aZvvvvvvPPB2""wEޞýdÜc\r!m``. r!t4N:XVVo߾}IRБ#GOixj th$Jwݷo߱cǚݼy3<<<<<޽{iiicƌ۷ݻO5-ׯ_>wܞ={'%%X+gذaIII/^ٳܹsׯ____f 5P6&&G\.7""͛y͛7#""\n=bbbjkkSرw@E:VVV|>?***??-EEE|+++X\YYIGZ 55!s܅U@PL$DǏǏE"H$*//Nz*B* tR\\,bӧOjӧbX$Sղhllr]P>>wdKc@ ]2VbTeOO9s8;;edd5 w]m5jԥKҜ̙e]`i0wYD" B BCC_~zhh(AB066V"ஈFuuuA=zw! t Z,x[nuGm۶mƌU i]t-rX,iQ;ҼܹC߁lmmׯ_O_&: S"H S$//Юv%ə3gW|hΝ666WB/ƕwUUUEGG#|||;СC>9aH$ߦjW_uiD"###rWYY vh͚5r\Pz !dmmM߱O>uT4)**׷Ϟ=eBԢgϞb rOQQ%ͶI٥z;g}6p@4ѭɉݻwcT?lذ.!jFUWWXZZ oi̙\v?leeE!t%t9}ӧO˔WHNrppp8׮] b䛊hhh W^>ΥK pwwB˫<<55!'P۸ҝ;wB> tə0aA={_>tjjjrrr֯_okkkaaNCSWWyfr\ĉ)_7c!jUA?~M9t>3CfHՍ/R~OmΟ?occJ6׽{͛7>6OoA``2+!t}P( $ jANӧ6`i"mrV+W¼4bVdvv6ݔ#w LKK# |.˗B-`,Ŝ4򎲋Kll,x$Irrr~~~mܹs RӧO<(ؿ?*XqZZ+ WW)S<|077XA,_חt(tH7n &9;;S8+4 |)SΟ?OIaXgggr7l onҥFFFܴiL&@.MvlsCsNDDdz/_]]^|)ɹZѣA.t@$EGGWTTஈJfff"wEԻqB6,::'ODGGDD95::ɓ'+˗/BO]<\,w֍a*77wE%w֭X,օwͷlق :oxyoy}uֽ{ȹvvv3#W]mSSe˖gϞӧτ pr}={~]l)BhfPK IDAT6/[,??Ν>D(Yݵ֬Y# k%$$丸 2d˖-B8;;COG(%i\S媵S^^.LMM [OJbDDDh]2vعst>}*̌:X$O7-,,|||=zDE?1b*@gAPehhHΥxa^x!>|د_ݻ:u5ط~₻ Y:8qA+W#Gܻwݽ{744WMM {,۷oϗJ CcǾ{ >..ɉʕ+/dff999ũvj\\u:ud@!ݿ G*"H6l@Fϔ)SLp7lؠഴ4;;;77[nٔ*--Eѱ3,Ya{ݻ)kӧ#F044ܹs'Umj\n``g܅NQ]LLL֮]p1MMM(ZNf'ww wS`p v܉?>x111{GY^^px\s C%\iӦH ,̘1#+++55K X@h*?~ѣG˖-(ěZ^zeff~}lA tnܸq /&$$|WW9sfmm-P($.t BkZmo۷E"B4:hР㮈^ӧ С͛===Ǎyw}}}> B:Ԩܽ{EضçMrJL"Z888| tc7o<܅A__?..n׮]6l=zgpWD=.=:mKLiӦ9syYǏ4ʕ+ˡ<5:HJJ*..^t)B:s޽{nݺw9 46l0fwww܅t{'OFFFᮈ2:uٳgQ"'&&;vlذaZ;:ڴiS^>܅t\"J tiP@(~w!:jسgϒ%K3233'N8nܸ5kr6:jٶmޜ9sp";vl޼o d\5 tT'J7op&.?=͛7oԨQ ^HHHfffEEŠA]4, tTӽ{~G ˗4hA@PUUU]]Ul۶$22w!4255=xڵk͚5K#$AtYSSw-"bٲe)))gΜ]QA:,eӧOIygeee 0ȑ#i a9.۸qĉɞptt %NlܸqРAÇ]{EEE߼yԜ t:VZZ;T6hР,r*z:,ӱ8KK3f.DXYYZ~B t:P__믿.X@__w-=zFz z : BZhB4ĉ\B.?x%&- Eqq1Bxeiiу޷o9vSN]  drKy)X = &333AGedd.JX>O.?A̶ṉ@WAO r!P(*++wMW_}'UeAf:on.MMM ӣG4hPbb"4Z``rG}86yCeeeJRЍ72 .,Zhʔ)t/?` AIIIDf~ƍ'LK`:\.f4k֬ Z3.yCee%τ$$$t~wUUU 0`…/d2YiizeZ@輡kX͛CBBԣ5k,X@B1c͛7lr)':wm濺m;vС/"99Y.s89s樼Ja'] +W̟??>>5˗/ϧ83^n;vlFFF]]kL/_\zjm\XXι`ȼgώ5 !dooOP(ܼys]]̙rB\.722R.cV\vM__A TkpРANNNkNT*߿?B/99YPD"ݻ⊊ BnCCuׯ===[MxoCn nfaaH$222211D!___D`s\ru\V@Ǵ6t$Ill@ "44gbAfffٌ >vZP\GEEQ@0tb Nj}v'_X]]b KKK>Ckt??? Z_aYm_S\t5*t***bq D"ѣGThױ'888++:AkcǎWp87onp5NiiH$211122Dj6NDppK(tqqqAx<q##bkͧSTToaa!={Fa㍍B( 11Arss>}WX>εй~DDϷ}MdlODä{-Y\ѱGp5FNVVVpp0qpp}53MKK{BJW5?}k-as%rH{||<{iiiBFkpƄNbbb@@Bw9xL&[ύ7"""8@ s:r>>>'&&b6w툈gcc#pW\9_~#G<="EGGԞsS:... 6{IttrjOii)4kĮ!'8;;s܈7nந˞?"E}}=NYl /_bkkkr͝;wBAAAHHۺu:?dCCCwwsfffv ҫWbccmmmɩ=W6G 84&Ċh333rMAA <ֶ)66H$gΜ!_˺;wp8]zHGGGrjիWUn/^ %k\ӧB%%%I4O},,,._LGiii#GDDa&Mj~㣏>bx"h= Ça:IOO'=<<D_®~Q+wޥH9 X*dEEE۷o'ׅ@mܸ;mh: "44t޽zpD{g&u֭ 333SByjjjrrr֯_okkkaaNCoHKK;v,yC–'Nzw(lm\ws}U')Cf{ B.zW\INTH$:tPUUH$IR [=B(??f纫(9+WoZv [^^^TTdz􍎍0arŋm?ZU9fС4k@ 6n}k1W\AAH$244455DԶuVwwwrL&ۺuw_T#z.L.tO8JNNFZCZs!1]ӧObH$Fzz^kΝ;G@*>}>J理Bbcc{IoygXXXAAjkk8P\3pi9S[nzzzo-#8NO_PPPm5SL9)уxMZnmʕzzzz/n sNjjjbcc8Nhh(,qVVV|>?***//wEJs>..ɉ)d_*//D"Us l됧'B( %%wEj)..Dbӧ+b8:-C" 8w:r~X,ң\Zg+tHr<11!)ݽ{744HAl %C}cU233i5NNNqqq+oee%++++DN!kOMs[aC ȩ=eee | -B06T<~4.ϵƥ)4,td2ٚ5k\nhhh^^X,677'TCP($"44r|̘1\.Rƅ\t ]ISRR2|p##xcbb,--ɩ=ž<׀*4GGG@¿cԞANLQNݻ:q8ղ ;׀ _~?BBo=ڵkM*Oټys;|>ۻTAW1pX: B"̘1P5K95..{777wh &#055򲳳!k\? @n\} 2___ 'NPٳgɭlll >7odϭ#wSSSrb1 g\ۓ䧟~]`Ydgg BWW۷ow==QFڵA4IIIApܐ􂃃 Eff%Ks=t˗)tN8ajj:rH5o⴯ !t!:_jՐ!C?YYY={tssx͚5kĉ4yk֬?~9sOKKK$HBt47dffZYY5322 q\nnnyyyHҨ/~ڸqM122(-ڦ,X 44R;ѣGL} Ѵ̨3gNbbݻg͚ di鴃C {nח9::EzjرɧOf&q!M>̙3/^/**RrssCvBѣG.] dX.p8~~~W^U155]:Çd/^$'0oOx…ݻc%ڭ:a۷o>G  211?"###""6oތ؀w=z۱c,,,>:BH"p\Ϗ[xqEE"ziU:FC#Gӧϱcp5jkk Mk֬qqq?~~~mY.؀+W>rGlqIO~mBddyxxxUU \-Nzo ۫Wȉr=+WÇg,qPJ$BhҤI'O<{qjjjpZߺ"xj=nܸ߿yZv{wSSSܹ{=w9=trrrF흘Ȇ,R8p`JJJiiiHHׯq8NϞ=#G;))%oyyԿ3g?|=h O=֖=X|y;拉=﨣͉ ;B&88:ǔ͗WJgϞ}رc:Zpy-^\\Ķg,RHMMχܡϫqh ?0--ɓt_^)?ətݻw:tLJէWJ?vؕ+WfϞ OQB(x<(?OmTH$! :رc'NOqע |3iW\7oއ~((lZ! >;v̚5k<#{:/^ܰaƍY8mJiƌs΍zZ4l SSS1eʔHj v\^)ϮMMMk00#C>H$ Mk.HѸk0X:g\\ƍY>*ZlzEGG-[;v w-M*vXt9tϟ?m4xFނD"aT:uY.\˹wl QCocЉW矹\.ٲUXc?ӆ lmmi*Z bŊ]ׯ_ojj_9Nn|IZlϦv5jԨSN6 w9TTTobbsNrhУXExۼϞ=v˥& ZXXr \P(R)B(11q„ Xk󓒒޽˶%bYq999Hnp5_Sօ˫ǏlڴIS!dllCUhhرc,X@v@ |=S#H>ɉ(ЧO?7nmyyy7n+Vh\ccA::D"Yr%dԩzzz,XA7:mҥk֬] -_w:8t tޝ0q?dqCիW#bbbpF+Wl `w%mllo׺uqF_T~8NHHtH=Tw͙3G& K*j-/^_.);;pig޽{y<ޣG@8qB!am˖-qPWWףGxSNHtYnԩS{Ic1#z-XPb޼y={;;m200ЁȌj'222BE &L@Akaȯ_ZZ6'oE_|||?M2EP{**sε]7!̴QMMц hͼ^z^VVt¢w!׿L?[om>|\?˗3OM]]3x8coҥ}opBܵtك|}}.b֭]6o {͇3744, 3fl޼YC!}%=/^3\ ŋoݺz[$%%qܐt)%:#FuӢE>} 3_ -,,v؁ ̚\kFgϝ;_ms=3F;wY >.\XRR|X:.\иA\\\ƌv-CG.gff>K5V-:uTnn.BNk:>|,/Ǝk.܅2t_ׯ_?,Zqܹsڵ n'Zݻw=<\SSZNAA R3e2١Cpt#HpUDh"kkkKKŋ744t999~5W( &M 9~t-88Xwh#Gu}̙%%%+<{ !|( HMM%bȑ/_ܻwo'_)pe˖6wIɓ'¸su>!aÆfgg.x!dmm.pBRRҒ%K߯_K۷ڵk|y}}=Q8 秦8qYYYi߽Q~bo?YPPn:uyBS1]FޘxoGڿ?ΚP(Mի{S&W(4ZZ !G?(8=:Ul?!J~K~|J@@@gt$''ԔUwʕe˖9::R3rssoݺEa,'$###$$VOO{l[o.B!:Nyy9B[nd픔dddxyy}7l{C^ۛv}}}>~Sl'D$]p!33իW۶m;p@TTMOoNSSBc*^|200 %㲲R iiiiii|rЦMhUU Dr…ׯ744޽[f 4iSUYY) &M:wwUg}×/_O!j;Ŕ`[a#?LRV" Iq\/B޽{T6ʕ+-,,z"~[4iҭ[=z~SE'jӦMB}O={_QQ1`3grP`` ڣ١RB Z# SE QΆ#?O>T堠 KKK J~CzzΝ;i*RM~iiiׯO?~x5?!VZv}y{{T$Uۗ2z蠠 ܵGC'""!J~={j]z!4}tBǎ#>Bh̘14>iҤ'OP ٶmB?D566R"EN<9o w}ɓ'4K+ ~SL<7Ay :tڴi}{l=pW H{:Ak˖-FFF(GaU}ut&LPWWיLPBG0hĈlh @#Fq9pAP(`@+,  !4bĈlr!hBhذa/.h?Bݺultq* ~?>uԼyvE"B\/;;w!B"ܹ׭[wersbmm CAS]]}ĉUV-\pEEE+oo7oB'888,]\D.*w9w\P}!tx{{CO1k׮ms&rti̡O.eB&&&xlUп\@dR/!!ؘ'&&у|3ɵI1+,,l~~~ X?+nnn2X7^_ĉ97&+FLJJd /abbafagpLQ$tɒ@{۶mV9-|VVV X[ٳ?#|7|?;kggBUX___ 7l_-Z: By|>fff^=**ի ܲe ) WX8::>| +W?ݻ˗?EM2ŋxxt0 { ?׏9|pZZڀ` xwqM]Ož*ą nQjZV՟uઢb*ֽ D@PCe>O BHn%7~3p9۷dW :.zѐ!C<<<|pSN]N7 t? "['&BHKK'AHOH!Xv@>>wss=rH aڵׯ_"CSlmmLgqQ\pB ,,,%%@ tWQQ葩SZ[[Bb#QrJt ߄SԄ֕ëg"Ə8n8P\\ bs!p3k֬KSSSM&fIII}!oW_}%Zs,ͱ0f777,++CIT|m;FݸqIGGGfǏ/m#HAu&cٲe?2:!===GfeݺuFFFx "!ϟ5k0L1qD\JNgʔ)Ǐ2:>}Bb?bKTWW󞐑`0mBXTT$G,^^^b4i$\N 7A e111="&á, /{X!˥hIMM4h$''[ZZJKPGGx ]Y`A]]ŋ{ NB>m۷8ڵk{űBܝ?~̙ⷓ$VH!&t`ԩ! 6˗/>}3fMihh?~BөD\ŋ?SUUCEzt 7+ .LNN.--~ Э[(D_ߟdU$rssutt,--l'--B}?OEzt 7SӧO/bbbzNۛvd@.ݷoϟpMMM\.~YfyF䪸ȳvڟ~Iv.\,~;&:z~s`cccRRRhnwo.֬Ycjjf|lNCC7|ӷo˗׷}ã-OMMݺ"rU\ɄUnnoӦMC19{ؙ&ࢨB$'' [md.tԾ'O .D(.@:{]...s:@7oիم|…Za XǏ| .dd2ҦLBv!@7ܹs<BGܹsdN:B={͛7kjj}&ILS{ IDATL166& f͚f\3!t͛7 HH>}Ǝ+(++{1ٳg_~kX:"11QUUU{?͞=b]vM tEbbمBp8III'O& f͚u zA(NI򪯯hdddkkKv!@ΙXZZ BG!ܼysr<'NLNNW[[ V&Lw!t_jj*Ñ0aB(55'@ȿ7o9wd#ցБpl$t*%%HBIIIqqޡŋ#G]^x ,&Lm۶W^v|бBHKKΎ*Bիd" P _`` %HjzzzC9>>Ϗ8m׮]6mz6ٵ(..B/B(>>B䄫Ç;>tBh,K~3+**222ğ=z46VG:!Իwooo?Bpvee対BqppxQCCCLJ t+444???//BtI&ijj]P8l6;??C:>dȐ( MmmmJJ [RXXX=|C:ZdӧG%&&Xӧ]PPvvv=B_rم̙3d]AAA:՝3gNdNyy /^Lv!@q 2oi'44K}2ɓdmmmmyy9rv\\\ &맓\cTUUɮ(. C[xq\\ܧO.DtϞ=[d مf``QRR·B߼yTLN1bСC.(4 2p@uuugϞ]`م PZZʷBd"Gl dqYYBN=zĈx:e݋/իٵ !t `pi_YYwߑ]!ddd;: 鱱d\.t$g``P__v!N455Ν{ak֬!KOO!TSSv!N-[VTTt ֮]GEv!N~ɍ7VZEv! BBCCϞ=[UUEv!۰aȑ#a UB|@ﯦ&.\a PSSSۅ:9rDO'oٲӓBhGYY!v!N7BCC矴4 Rnnŋ7nHv!hT*Bn :YO'o޼|҉NCXhh{ ă\~z s,F]=___MM͘ իlZfcgvx t6o޼(Cv-;w.55u߾} Zv`E.ҥK_xqm Wss?8w\GGGksu+͘1ct+**~7 K!mm !tz…CۓǏ7o 366&u:C@GWWWJN'o޼YUU.Z)##G~:ׯ: Ё+хz*992.]joo|rr[:h{:wΜ9sRiWVVfhhwKYȨРo>}СC/_L&ԬZjɒ%0R׭[Phh(m455IO.-gggUUU;;ϟ?ST˦&b&_lmؖ{فCv…Ç'@yi.PX,VBBرc̚>QnF}m߾wiĈ `٭@իW&&&| !t뛑rY,ߣY|aN͛7} N "S\\laaBG(ÇWRR7Iy޽X8@Q00E?}dnnηB9tдi:KJJ6lO?YYYItCƆo!B2d5)%ɓ鈈J 6ܑ]dڵk%5|%vSh4Zpp0Yȓϟ+++9ѩ]vظcH4tbbbܹpf.ad#Omll:@@>}455ێFR%:>|Xf͊+ &M(8ѣGΔQTGG[|(((:th:=cnn~M:λɒFI.t.\e BOB^ :.1xTr{:QQQ׮];y򤺺$?|𡬬ֶC:#}}l6=={8qHڜ9st:N={6ٵȉѣGw]\x1"czzz&M¥ALAAA5|p92#f[dooob6rӧ-q{O>Ji;Kw||-&5JB.ۣe޼ys]9|}}.g؋'Iy#ĉmfdd0n.8::u55)TjTTANNN~~~kk+I|R 77[!DFF}!dllZlB())H%Ν;Ӛ:=vر۷oR(-xDX<<>BHjjqRSS6C4pNйyҤI&R+0._u tl}||F{㰧wB =@;o߾W^mcc#!t\R__?""BB_/^oܸ!Dz€=~~~SLV t^SSsNn!;wX=*--o-Z-mAlvPP޽{ ^mۖ%VB=Zvv͛7n8bb*//'l:(iӦ;wNI3-pNիwjii]O:u9+++7 W(ׯ^:""b֬YoB`0fϞ|r# Bk.j@QN6166J%wB3f+..NYYJ򯦦fʔ)YYYzzzĉkkk322$=l0 tgXԤ]B:ȱZOO߾}[JdUuu)SJKKoݺ5h r!//A o=z_]?JffСCH:)Dž Lzybrb׮]gϞ1cƹs.KpԴ`ݻw\r˗/9B7Jnni j̙>LHH `*AEѪ\n6449lȞ?>k֬ʛ7o]PPP&&&cƌt*ڿ+W=ZYY9''GVAE$CҀb\rƌYYY2qO{:4mΜ9#ooCEFFFEE]Q@ť7ydv!F|TVVv) EGt:?dWlC\]])q!??V???kAEEEnnn+W OOO "AƎ?vXhiiYvy dWOAECh4󟖖R5jԁ<9x`R P\L&sK,qqqqqqYdL&ae455mڴՕNgff88m9so rÇڪaaa/_Ė|2,,LUUU[[;<<Ǐի{immP,o߾ TWWpuuuMMͰoJS԰0Mz@E eee==*ϯSVV z9^0p:>jԨ\:@=}4((NFFF nmmmdd!N z\zuڑ r<BȳӧSTcczک466RӧOm, !+*:@>eddL8!4hРflnn8qbff+//_ͥKƌ1bĥKl6x>1c\tIoޫW/CCØ܋E:@N옘aÆ!/]p$9s%GGGаa6pbbbLLLo.25&&!4}tA vgkkNMMuppPRR 22dFFFQ(ӧ߹sJ )#B0a;}t\m Wcc;V^˗/crHzʪ'\*ھxӧOJJJ!!!dWį8$$DIII__?""ӧOdW$] t(// RSSkaJ:aݸԴɮHZ@͛0 J+VeeeDDq ՞={uիWDDćȮH|ݸ={FvEdRɓ'شX:yűc _O555KK dggPER}||Sލ/_Μ9SGGb BHlTDnޞ7k566`k}d~?۷/J믿D655EEEƕ#Nk=ջQUUe``6d###%W"eo++\itVbb"BhРA◄]S3fLrrm ڰa˱-,,$X@ t).X܌9Sx6^K.1Dk0_-ǏB+ndb'N>|3\OOO 3f[V)..F8d:Jrvƌ#F8qk?MF@rX'Nϟ? #++S:'ꮯOJJ;wmBxzzfee1 cc۟8q7ٱ5Fa-B(88XkWX)SSSTFF.Zm 4ɓ' idd$ķ}ƍMMM%'BD7==-:\.h޽$MKK۷/B(<<ߖڒ7 VTTF:tH+B3txܹ9r$~ud؞3|hjj5j֭[\'ܹs!S @IIIXXJ>}"""%-B!_iTWWGDDGEE%,,D[ .q8nׯ_GHhc)--m+L[+t222B666_eeeٸJKKqOѣG---?rlѣG &`߿UQQ y5^-766&%%ukZL&355[˗,2>>~ %..\ׯCBBTTTtuu#""޿c|z7222Κ*ݶsssB/^YTT$~.:;;uJAIDAT{xxN722NKK*LQQ6W޽oNFW_J\vPAA6@^ú&ݻww=sY~D*څϟBׯ_'0 SؽQ2dF 8'_7. |yPP1O`B֭[NNN!Ǐ X622NURaa!a 22G'{ ݂x]r7n\VV׷ƕ'N1X)ccH)::`kk?\ |BXg#G&%%֍!4qD3'33}a``%1a]LL –!&L`0$T"UV }777nPb2tnn iMMM۷on#O:pԩƥ(ܮ0aĺ.[VTTZjd;d PX`ɓ' (.0te˖M2ٳg% 2݄Nccٳg ('''??!C|JvQLݏ_xj<)++ q8u-[TUU\~ӧE%ll;;aÆ:uJ5YrϞ=q '( =GѶlLBBvc1${:iӦh4\ZZ333}||6l؀ zvsO<9zR&M;v,NȈ=ճб^tMjjj$TNϟ?5jTuuuRRRjj E"""8κu$Q B^ 2dH~~3gx N޽|...f!. GD]yϞ=JJJwf Z[[?|@vE@>xxӧO󵴴B@$lm۶-]t͚5d P(Ǐ7668Xlٲɓ'?{%'}ݻwѣG]WA0ovvv/^Ɂ)v߾}{BB. UTTܻw/..pc1 ^ -Zɓ'&&&x5 ۷8p@[[{pc1ߧͅˮ䪫۵k9ڵkWXAvQ o \\\ L@]v555}aaaz"(s ^|8v3g"a7_eeUV^OvQ333s]xqǎ7:r-[6ugϞm߾H'Loׯ_Dd'''???[[[ltKuʕ_9s222$ `0\]]'M}x H? N/}᯾/˓VÇ'MNR FRRѣ. H0th4ɓ']\\BG$i9V\\;r>$%%]= A)++߃ >> i*B֭Qmɟ>}MC9sFszc͛6m搨EE$DztDMa|رfZr]=%iW>aaa؁^uuʁȮU<|L0̙3dW$Azzz!~Ǐ]BЉ FX!O:,`xl0l3g͛0`@nnnNN-33֭[FFF?=Q>'))iFFF!*l2;;***ƍ۽{7Bĉd@gؤ$]vU1&O.c dcO[IIIuuumw#G]tА!C.I8qbڴimblv-XNRIݻwB| م= &`00LPSSSfffۅ=ںuߍ9o޼YlYUUB1%%{=f9''gΜ9CmzKKKVVT1-,,fϞիW,\1nCɝqcW/ϟ?>566v[0w$wUƷ~>rlDIdй#| bNطo߾}.I@.A P:BA P:BA P:BA P:B9r/a@[EBBBhh(YHU (R20@A9 t B@>82̟IENDB`tins-1.32.1/examples/length_difference.mtm0000644000004100000410000000100614353307475020603 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with two [ab]* strings on the tapes: # $ turing.rb prefix-equals-suffix-reversed-with-infix.stm ab ababab 1. right 1, goto: 2 2. right 2, goto: 3 3. cond 1, if: 'B', then: 5, else: 4 4. cond 2, if: 'B', then: 9, else: 1 5. cond 2, if: 'B', then: 13, else: 6 6. write 0, symbol: 'b', goto: 7 7. right 0, goto: 8 8. right 2, goto: 5 9. write 0, symbol: 'a', goto: 10 10. right 0, goto: 11 11. right 1, goto: 12 12. cond 1, if: 'B', then: 13, else: 9 13. halt tins-1.32.1/examples/recipe.rb0000755000004100000410000000304114353307475016231 0ustar www-datawww-data#!/usr/bin/env ruby require 'tins/xt' $:.unshift 'examples' require 'recipe_common' class Cup < Unit; end class Teaspoon < Unit; end class Tablespoon < Unit; end class Flour < Ingredient; end class Bakingpowder < Ingredient; end class Salt < Ingredient; end class Egg < Ingredient; end class Milk < Ingredient; end class Butter < Ingredient; end class Recipe < Tins::BlankSlate.with(:respond_to?, :instance_exec, :inspect, /^deflect/) include Tins::Deflect def initialize(&block) @ingredients = [] deflector = Deflector.new do |number, id, name| if unit = Unit.unit(name, number) unit else ingredient = Ingredient.ingredient(name, number) @ingredients << ingredient end end deflect(Numeric, :method_missing, deflector) do instance_exec(&block) end end attr_reader :ingredients def to_a @ingredients end alias to_ary to_a def to_s to_a * "\n" end alias inspect to_s def method_missing(name, *args) name = name.to_s.gsub(/_/, '').capitalize @ingredients << Object.const_get(name).new(*args) end end class RecipeInterpreter def recipe(&block) Recipe.new(&block) end end recipe_source = < 1 ? 's' : ''}" end end tins-1.32.1/examples/turing.rb0000755000004100000410000001607414353307475016304 0ustar www-datawww-data#!/usr/bin/env ruby require 'term/ansicolor' require 'tins' module Turing class Tape def initialize(*initials) @left = [] @head = 'B' @right = [] c = 0 first = true for initial in initials if first c += 1 first = false else @left.push 'B' c += 1 end for s in initial.split(//) @left.push s c += 1 end end c.times { left } end def read @head end def write(symbol) @head = symbol self end def left @right.push @head @head = @left.pop || 'B' self end def right @left.push @head @head = @right.pop || 'B' self end def clear @left.clear @right.clear @head = 'B' self end def to_s "#{@left.join}#{Term::ANSIColor.red(@head)}#{@right.join.reverse}" end alias inspect to_s end module States class State attr_accessor :tape end class Cond < State def initialize(opts = {}) @if, @then, @else = opts.values_at :if, :then, :else end def execute tape.read == @if ? @then : @else end def to_s "if #@if then #@then else #@else" end def to_graphviz(stateno, tapeno = nil) %{#{stateno} [ shape=diamond label="#{tapeno && "#{tapeno}: "}#@if" ]; #{stateno} -> #@then [ taillabel="+" ]; #{stateno} -> #@else [ taillabel="-" ]; #{stateno} -> #{stateno} [ label="#{stateno}" weight=4.0 color=transparent ];} end end class Left < State def initialize(opts = {}) @goto = opts[:goto] end def execute tape.left @goto end def to_s "left, goto #@goto" end def to_graphviz(stateno, tapeno = nil) %{#{stateno} [ shape=rect label="#{tapeno && "#{tapeno}: "}L" ]; #{stateno} -> #@goto; #{stateno} -> #{stateno} [ label="#{stateno}" weight=4.0 color=transparent ];} end end class Right < State def initialize(opts = {}) @goto = opts[:goto] end def execute tape.right @goto end def to_s "right, goto #@goto" end def to_graphviz(stateno, tapeno = nil) %{#{stateno} [ shape=rect label="#{tapeno && "#{tapeno}: "}R" ]; #{stateno} -> #@goto; #{stateno} -> #{stateno} [ label="#{stateno}" weight=4.0 color=transparent ];} end end class Write < State def initialize(opts = {}) @symbol, @goto = opts.values_at :symbol, :goto end def execute tape.write @symbol @goto end def to_s "write #@symbol, goto #@goto" end def to_graphviz(stateno, tapeno = nil) %{#{stateno} [ shape=rect label="#{tapeno && "#{tapeno}: "}#@symbol" ]; #{stateno} -> #@goto; #{stateno} -> #{stateno} [ label="#{stateno}" weight=4.0 color=transparent ];} end end class Halt < State def initialize(opts = {}) end def execute -1 end def to_s 'halt' end def to_graphviz(stateno, tapeno = nil) %{#{stateno} [ shape=rect label="HALT" ]; #{stateno} -> #{stateno} [ label="#{stateno}" weight=4.0 color=transparent ];} end end end class BaseMachine def initialize(program = nil, &block) @states = [] if program block_given? and raise "use either program source string or a block" interpret program else instance_eval(&block) end end def step(*tapes) @stepping = true run(*tapes) end end class SingleTapeMachine < BaseMachine include Tins::Deflect include Tins::Interpreter def initialize(program = nil) deflector = Deflector.new do |number, id, name, *args| opts = Hash === args.last ? args.pop : {} state = States.const_get(name.to_s.capitalize).new(opts) @states[number] = state end deflect_start(Integer, :method_missing, deflector) super ensure deflect_stop(Integer, :method_missing) if deflect?(Integer, :method_missing) end def run(*tape) @tape = Tape.new(*tape) @states.each { |s| s and s.tape = @tape } goto_state = -1 @states.any? { |s| goto_state += 1; s } begin printf "%3u: %s", goto_state, @tape @stepping ? STDIN.gets : puts goto_state = @states[goto_state].execute end until goto_state < 0 end def to_s result = '' @states.each_with_index do |state, i| result << "%3u. %s\n" % [ i, state ] end result end def to_graphviz result = "digraph {\n" start_edge = false @states.each_with_index do |state, stateno| state or next unless start_edge result << "start [ fontcolor=transparent color=transparent ];" result << "start -> #{stateno};" start_edge = true end result << state.to_graphviz(stateno) << "\n" end result << "}\n" end end class MultiTapeMachine < BaseMachine include Tins::Deflect include Tins::Interpreter def initialize(program = nil) deflector = Deflector.new do |number, id, name, *args| opts = Hash === args.last ? args.pop : {} tape, = *args state = States.const_get(name.to_s.capitalize).new(opts) @states[number] = [ tape, state ] end deflect_start(Integer, :method_missing, deflector) super ensure deflect_stop(Integer, :method_missing) if deflect?(Integer, :method_missing) end def run(*tapes) tapes.unshift '' @tapes = tapes.map { |tape| Tape.new(tape) } goto_state = -1 @states.any? { |s| goto_state += 1; s } begin printf "%3u: %s", goto_state, @tapes * ' ' @stepping ? STDIN.gets : puts tape, state = @states[goto_state] state.tape = tape ? @tapes[tape] : nil goto_state = state.execute end until goto_state < 0 end def to_s result = '' @states.each_with_index do |(tape, state), i| result << "%3u. %1u: %s\n" % [ i, tape, state ] end result end def to_graphviz result = "digraph {\n" start_edge = false @states.each_with_index do |(tapeno,state), stateno| state or next unless start_edge result << "start [ fontcolor=transparent color=transparent ];" result << "start -> #{stateno};" start_edge = true end result << state.to_graphviz(stateno, tapeno) << "\n" end result << "}\n" end end end if $0 == __FILE__ and ARGV.any? include Turing filename, *tapes = ARGV machine_type = case ext = File.extname(filename) when '.stm' SingleTapeMachine when '.mtm' MultiTapeMachine else raise "unknown turing machine suffix: #{ext}, use .stm or .mtm" end tm = machine_type.new(File.read(filename)) $DEBUG ? tm.step(*tapes) : tm.run(*tapes) end tins-1.32.1/examples/add_one.stm0000644000004100000410000000060114353307475016547 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with a binary number on the tape: # $ turing.rb add_one.stm 1111010101 0. right :goto => 1 1. cond :if => 'B', :then => 2, :else => 0 2. left :goto => 3 3. cond :if => '1', :then => 4, :else => 5 4. write :symbol => '0', :goto => 2 5. write :symbol => '1', :goto => 6 6. right :goto => 7 7. cond :if => 'B', :then => 8, :else => 6 8. halt tins-1.32.1/examples/subtract.reg0000644000004100000410000000047414353307475016767 0ustar www-datawww-data# vim: set filetype=ruby: # Subtraction A = A - B, A >= 0 and A >= B register.A = 10 # register names have to be uppercase register.B = 3 label(Sub_B) { decrement B, Stop, Sub_A } # labels have to be uppercase as well label(Sub_A) { decrement A, Stop, Sub_B } label(Stop) { halt } tins-1.32.1/examples/add_one.png0000644000004100000410000011167414353307475016545 0ustar www-datawww-dataPNG  IHDR|4*bKGD IDATxw\3[MJ56JQQ * +ƨk&A7YM#1Xbcl[ (D myܽHٝ3|{YgyfBP ` w`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA .\x5U< t[l]B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B(B.]k.)))ѣm~,Y28UVK&9::2_.Mjj ˝5ksRPPuV~=H8:B0dRy<ޜ9sp+//۷o7₱*0DFFr\A 0G@̘1C.+p8X`322p8666`TDD A:Q!P(t `TnFI ]B0mΜ9 bݺu] @7} H&<~x `۶m;xzBB(p0܅@O˵/'AKo{:FA`Q:FA`Q:FA`Q:FA(SPP}3guUěCBBN>M_Pm%@ɓ'{I_U[[̗}=x>ضm=E `@ (Ya\4rСC{#c@&@zB t/++C 06:uWZeooqFܵA&uk,}}CY@@Q(K,A.BKLLˉ'֯_@ .;v "::֭[ԃxↆ3f.P BP.%%jhhx"3g/ݻ7k֬ VM;otl+ (cddݷmk``zԨQ&M:z(y5bĈ#G9rUC:2ꫂr9eQ "FMpy`Q:FA`Q:FA`Q:FA`Q:FA`端ںuk_P455|jsss_4k/ʕ+=zԥܽ{cƌr*̙3*׭[׭[7B(!!a{9sj-[nŊpJ_W{y.]r 233 xc( t@UWW2.%%Sݓ'O\;w޶G 2]##""$ɁI'O d2蚯Ӈѣ:V?N]p5klذaСj6ɯe2۷?v@=YyyyC 6mږ-[o- \.o߾7n܀;;ZBtJmm lM*444'Ǝf t/^=zTAݹsux/BA耎[ vvv4xORiVVVrr2%:p>,&&& 6/_y<ի: `'SPP0x]vQج[~~oVV)<`VuuuA\xАfuP(|>AMMM䇐yxx$%%Qx86x geeQzzz...'Oζiz:m%KN<9zhZt)SH$ZXamHKKDN@ P(th,,,lҤI?8P(D2p,: ӦMܹs'33ufnncn$7|'411a:vܹiӦ#Gxzz2y\@; %++룏>ZjդI>P(+BŋSN1bė_~ѡS td|>2ccc# ttWUUɓ vZܵ '''%###ܾ*Bz:: `An_uyܵ @ ]`tt}ƍ߾*0TGw@蜼ٳgϟ?kPX\\,qh[jkkLҧOw-oeee ! "22ŋ -}YWXBG[رcj* Cxz+N>vZܵP=-$J}~A~AA̙3#"">c`hϧ]|ygʔ)Bp͸Kk:Z~xR4))O>/))|* /BGH$#GHRPSSSIIIII'|B>b3@PTTP(Ytd2LwEGGd2uH ={ w!^:fmvWWW3_R'X:BG;v\.?+$O͵V?nN Yf}gY<z:Zn$kݻw r{}aÆa`.xYjjjk+>;w?ql=Am6wwwUu@ ~:*=C{x;w}ւUl̬[np[Gk)@' 8k?nkk<66UKEEEmmszںuj4jAٚU() thaCCׯ5 !iӦNhזFFFAAAoUl 6b:;r}||lmmcccB4z5Qڷ O͵v9n8k777B F t6BGAnРA\.!rkV߸q#5Qڷ) ) v- .\iii|?tМ"|]"r9 J:Ϗݳg /W(K,AR]e|$r| \ai%444\2 @Fbbb\\\N8~z k%o!diiijj CD"ʕ+B BFwADtt[MKV:Lضmٳg7 rɑ,* ZxqCCÌ3ꨭSMM thx\ \ f͚6_pE3g466^dݻwo֬Ys"6mv,奭 th7uT2,8Ό3 6_k``3jԨ0"ȑ#NNNTey]Kyi+˜vxRedPP\.W,9̺5@PZZ*Jyyw!J:`,^OOnh^z:ZB >:੹} tWo[Wh"j@"<w!2:?}tB LLLpV>dҽ/RYYzjZ҂rrvrppr?@TZZ: >Ro,a9\.KIGKA0- e2X,Rf!h:y{{7 ~qY`a8p`@7K`)/MᆱG~p<=='M$ 5Ea Nޒ4@ (** *ߟLhxx84P(lhhx)B t0puuEzj\%aZvvvvvvPPB2""wEޞýdÜc\r!m``. r!t4N:XVVo߾}IRБ#GOixj th$Jwݷo߱cǚݼy3<<<<<޽{iiicƌ۷ݻO5-ׯ_>wܞ={'%%X+gذaIII/^ٳܹsׯ____f 5P6&&G\.7""͛y͛7#""\n=bbbjkkSرw@E:VVV|>?***??-EEE|+++X\YYIGZ 55!s܅U@PL$DǏǏE"H$*//Nz*B* tR\\,bӧOjӧbX$Sղhllr]P>>wdKc@ ]2VbTeOO9s8;;edd5 w]m5jԥKҜ̙e]`i0wYD" B BCC_~zhh(AB066V"ஈFuuuA=zw! t Z,x[nuGm۶mƌU i]t-rX,iQ;ҼܹC߁lmmׯ_O_&: S"H S$//Юv%ə3gW|hΝ666WB/ƕwUUUEGG#|||;СC>9aH$ߦjW_uiD"###rWYY vh͚5r\Pz !dmmM߱O>uT4)**׷Ϟ=eBԢgϞb rOQQ%ͶI٥z;g}6p@4ѭɉݻwcT?lذ.!jFUWWXZZ oi̙\v?leeE!t%t9}ӧO˔WHNrppp8׮] b䛊hhh W^>ΥK pwwB˫<<55!'P۸ҝ;wB> tə0aA={_>tjjjrrr֯_okkkaaNCSWWyfr\ĉ)_7c!jUA?~M9t>3CfHՍ/R~OmΟ?occJ6׽{͛7>6OoA``2+!t}P( $ jANӧ6`i"mrV+W¼4bVdvv6ݔ#w LKK# |.˗B-`,Ŝ4򎲋Kll,x$Irrr~~~mܹs RӧO<(ؿ?*XqZZ+ WW)S<|077XA,_חt(tH7n &9;;S8+4 |)SΟ?OIaXgggr7l onҥFFFܴiL&@.MvlsCsNDDdz/_]]^|)ɹZѣA.t@$EGGWTTஈJfff"wEԻqB6,::'ODGGDD95::ɓ'+˗/BO]<\,w֍a*77wE%w֭X,օwͷlق :oxyoy}uֽ{ȹvvv3#W]mSSe˖gϞӧτ pr}={~]l)BhfPK IDAT6/[,??Ν>D(Yݵ֬Y# k%$$丸 2d˖-B8;;COG(%i\S媵S^^.LMM [OJbDDDh]2vعst>}*̌:X$O7-,,|||=zDE?1b*@gAPehhHΥxa^x!>|د_ݻ:u5ط~₻ Y:8qA+W#Gܻwݽ{744WMM {,۷oϗJ CcǾ{ >..ɉʕ+/dff999ũvj\\u:ud@!ݿ G*"H6l@Fϔ)SLp7lؠഴ4;;;77[nٔ*--Eѱ3,Ya{ݻ)kӧ#F044ܹs'Umj\n``g܅NQ]LLL֮]p1MMM(ZNf'ww wS`p v܉?>x111{GY^^px\s C%\iӦH ,̘1#+++55K X@h*?~ѣG˖-(ěZ^zeff~}lA tnܸq /&$$|WW9sfmm-P($.t BkZmo۷E"B4:hР㮈^ӧ С͛===Ǎyw}}}> B:Ԩܽ{EضçMrJL"Z888| tc7o<܅A__?..n׮]6l=zgpWD=.=:mKLiӦ9syYǏ4ʕ+ˡ<5:HJJ*..^t)B:s޽{nݺw9 46l0fwww܅t{'OFFFᮈ2:uٳgQ"'&&;vlذaZ;:ڴiS^>܅t\"J tiP@(~w!:jسgϒ%K3233'N8nܸ5kr6:jٶmޜ9sp";vl޼o d\5 tT'J7op&.?=͛7oԨQ ^HHHfffEEŠA]4, tTӽ{~G ˗4hA@PUUU]]Ul۶$22w!4255=xڵk͚5K#$AtYSSw-"bٲe)))gΜ]QA:,eӧOIygeee 0ȑ#i a9.۸qĉɞptt %NlܸqРAÇ]{EEE߼yԜ t:VZZ;T6hР,r*z:,ӱ8KK3f.DXYYZ~B t:P__믿.X@__w-=zFz z : BZhB4ĉ\B.?x%&- Eqq1Bxeiiу޷o9vSN]  drKy)X = &333AGedd.JX>O.?A̶ṉ@WAO r!P(*++wMW_}'UeAf:on.MMM ӣG4hPbb"4Z``rG}86yCeeeJRЍ72 .,Zhʔ)t/?` AIIIDf~ƍ'LK`:\.f4k֬ Z3.yCee%τ$$$t~wUUU 0`…/d2YiizeZ@輡kX͛CBBԣ5k,X@B1c͛7lr)':wm濺m;vС/"99Y.s89s樼Ja'] +W̟??>>5˗/ϧ83^n;vlFFF]]kL/_\zjm\XXι`ȼgώ5 !dooOP(ܼys]]̙rB\.722R.cV\vM__A TkpРANNNkNT*߿?B/99YPD"ݻ⊊ BnCCuׯ===[MxoCn nfaaH$222211D!___D`s\ru\V@Ǵ6t$Ill@ "44gbAfffٌ >vZP\GEEQ@0tb Nj}v'_X]]b KKK>Ckt??? Z_aYm_S\t5*t***bq D"ѣGThױ'888++:AkcǎWp87onp5NiiH$211122Dj6NDppK(tqqqAx<q##bkͧSTToaa!={Fa㍍B( 11Arss>}WX>εй~DDϷ}MdlODä{-Y\ѱGp5FNVVVpp0qpp}53MKK{BJW5?}k-as%rH{||<{iiiBFkpƄNbbb@@Bw9xL&[ύ7"""8@ s:r>>>'&&b6w툈gcc#pW\9_~#G<="EGGԞsS:... 6{IttrjOii)4kĮ!'8;;s܈7nந˞?"E}}=NYl /_bkkkr͝;wBAAAHHۺu:?dCCCwwsfffv ҫWbccmmmɩ=W6G 84&Ċh333rMAA <ֶ)66H$gΜ!_˺;wp8]zHGGGrjիWUn/^ %k\ӧB%%%I4O},,,._LGiii#GDDa&Mj~㣏>bx"h= Ça:IOO'=<<D_®~Q+wޥH9 X*dEEE۷o'ׅ@mܸ;mh: "44t޽zpD{g&u֭ 333SByjjjrrr֯_okkkaaNCoHKK;v,yC–'Nzw(lm\ws}U')Cf{ B.zW\INTH$:tPUUH$IR [=B(??f纫(9+WoZv [^^^TTdz􍎍0arŋm?ZU9fС4k@ 6n}k1W\AAH$244455DԶuVwwwrL&ۺuw_T#z.L.tO8JNNFZCZs!1]ӧObH$Fzz^kΝ;G@*>}>J理Bbcc{IoygXXXAAjkk8P\3pi9S[nzzzo-#8NO_PPPm5SL9)уxMZnmʕzzzz/n sNjjjbcc8Nhh(,qVVV|>?***//wEJs>..ɉ)d_*//D"Us l됧'B( %%wEj)..Dbӧ+b8:-C" 8w:r~X,ң\Zg+tHr<11!)ݽ{744HAl %C}cU233i5NNNqqq+oee%++++DN!kOMs[aC ȩ=eee | -B06T<~4.ϵƥ)4,td2ٚ5k\nhhh^^X,677'TCP($"44r|̘1\.Rƅ\t ]ISRR2|p##xcbb,--ɩ=ž<׀*4GGG@¿cԞANLQNݻ:q8ղ ;׀ _~?BBo=ڵkM*Oټys;|>ۻTAW1pX: B"̘1P5K95..{777wh &#055򲳳!k\? @n\} 2___ 'NPٳgɭlll >7odϭ#wSSSrb1 g\ۓ䧟~]`Ydgg BWW۷ow==QFڵA4IIIApܐ􂃃 Eff%Ks=t˗)tN8ajj:rH5o⴯ !t!:_jՐ!C?YYY={tssx͚5kĉ4yk֬?~9sOKKK$HBt47dffZYY5322 q\nnnyyyHҨ/~ڸqM122(-ڦ,X 44R;ѣGL} Ѵ̨3gNbbݻg͚ di鴃C {nח9::EzjرɧOf&q!M>̙3/^/**RrssCvBѣG.] dX.p8~~~W^U155]:Çd/^$'0oOx…ݻc%ڭ:a۷o>G  211?"###""6oތ؀w=z۱c,,,>:BH"p\Ϗ[xqEE"ziU:FC#Gӧϱcp5jkk Mk֬qqq?~~~mY.؀+W>rGlqIO~mBddyxxxUU \-Nzo ۫Wȉr=+WÇg,qPJ$BhҤI'O<{qjjjpZߺ"xj=nܸ߿yZv{wSSSܹ{=w9=trrrF흘Ȇ,R8p`JJJiiiHHׯq8NϞ=#G;))%oyyԿ3g?|=h O=֖=X|y;拉=﨣͉ ;B&88:ǔ͗WJgϞ}رc:Zpy-^\\Ķg,RHMMχܡϫqh ?0--ɓt_^)?ətݻw:tLJէWJ?vؕ+WfϞ OQB(x<(?OmTH$! :رc'NOqע |3iW\7oއ~((lZ! >;v̚5k<#{:/^ܰaƍY8mJiƌs΍zZ4l SSS1eʔHj v\^)ϮMMMk00#C>H$ Mk.HѸk0X:g\\ƍY>*ZlzEGG-[;v w-M*vXt9tϟ?m4xFނD"aT:uY.\˹wl QCocЉW矹\.ٲUXc?ӆ lmmi*Z bŊ]ׯ_ojj_9Nn|IZlϦv5jԨSN6 w9TTTobbsNrhУXExۼϞ=v˥& ZXXr \P(R)B(11q„ Xk󓒒޽˶%bYq999Hnp5_Sօ˫ǏlڴIS!dllCUhhرc,X@v@ |=S#H>ɉ(ЧO?7nmyyy7n+Vh\ccA::D"Yr%dԩzzz,XA7:mҥk֬] -_w:8t tޝ0q?dqCիW#bbbpF+Wl `w%mllo׺uqF_T~8NHHtH=Tw͙3G& K*j-/^_.);;pig޽{y<ޣG@8qB!am˖-qPWWףGxSNHtYnԩS{Ic1#z-XPb޼y={;;m200ЁȌj'222BE &L@Akaȯ_ZZ6'oE_|||?M2EP{**sε]7!̴QMMц hͼ^z^VVt¢w!׿L?[om>|\?˗3OM]]3x8coҥ}opBܵtك|}}.b֭]6o {͇3744, 3fl޼YC!}%=/^3\ ŋoݺz[$%%qܐt)%:#FuӢE>} 3_ -,,v؁ ̚\kFgϝ;_ms=3F;wY >.\XRR|X:.\иA\\\ƌv-CG.gff>K5V-:uTnn.BNk:>|,/Ǝk.܅2t_ׯ_?,Zqܹsڵ n'Zݻw=<\SSZNAA R3e2١Cpt#HpUDh"kkkKKŋ744t999~5W( &M 9~t-88Xwh#Gu}̙%%%+<{ !|( HMM%bȑ/_ܻwo'_)pe˖6wIɓ'¸su>!aÆfgg.x!dmm.pBRRҒ%K߯_K۷ڵk|y}}=Q8 秦8qYYYi߽Q~bo?YPPn:uyBS1]FޘxoGڿ?ΚP(Mի{S&W(4ZZ !G?(8=:Ul?!J~K~|J@@@gt$''ԔUwʕe˖9::R3rssoݺEa,'$###$$VOO{l[o.B!:Nyy9B[nd픔dddxyy}7l{C^ۛv}}}>~Sl'D$]p!33իW۶m;p@TTMOoNSSBc*^|200 %㲲R iiiiii|rЦMhUU Dr…ׯ744޽[f 4iSUYY) &M:wwUg}×/_O!j;Ŕ`[a#?LRV" Iq\/B޽{T6ʕ+-,,z"~[4iҭ[=z~SE'jӦMB}O={_QQ1`3grP`` ڣ١RB Z# SE QΆ#?O>T堠 KKK J~CzzΝ;i*RM~iiiׯO?~x5?!VZv}y{{T$Uۗ2z蠠 ܵGC'""!J~={j]z!4}tBǎ#>Bh̘14>iҤ'OP ٶmB?D566R"EN<9o w}ɓ'4K+ ~SL<7Ay :tڴi}{l=pW H{:Ak˖-FFF(GaU}ut&LPWWיLPBG0hĈlh @#Fq9pAP(`@+,  !4bĈlr!hBhذa/.h?Bݺultq* ~?>uԼyvE"B\/;;w!B"ܹ׭[wersbmm CAS]]}ĉUV-\pEEE+oo7oB'888,]\D.*w9w\P}!tx{{CO1k׮ms&rti̡O.eB&&&xlUп\@dR/!!ؘ'&&у|3ɵI1+,,l~~~ X?+nnn2X7^_ĉ97&+FLJJd /abbafagpLQ$tɒ@{۶mV9-|VVV X[ٳ?#|7|?;kggBUX___ 7l_-Z: By|>fff^=**ի ܲe ) WX8::>| +W?ݻ˗?EM2ŋxxt0 { ?׏9|pZZڀ` xwqM]Ož*ą nQjZV՟uઢb*ֽ D@PCe>O BHn%7~3p9۷dW :.zѐ!C<<<|pSN]N7 t? "['&BHKK'AHOH!Xv@>>wss=rH aڵׯ_"CSlmmLgqQ\pB ,,,%%@ tWQQ葩SZ[[Bb#QrJt ߄SԄ֕ëg"Ə8n8P\\ bs!p3k֬KSSSM&fIII}!oW_}%Zs,ͱ0f777,++CIT|m;FݸqIGGGfǏ/m#HAu&cٲe?2:!===GfeݺuFFFx "!ϟ5k0L1qD\JNgʔ)Ǐ2:>}Bb?bKTWW󞐑`0mBXTT$G,^^^b4i$\N 7A e111="&á, /{X!˥hIMM4h$''[ZZJKPGGx ]Y`A]]ŋ{ NB>m۷8ڵk{űBܝ?~̙ⷓ$VH!&t`ԩ! 6˗/>}3fMihh?~BөD\ŋ?SUUCEzt 7+ .LNN.--~ Э[(D_ߟdU$rssutt,--l'--B}?OEzt 7SӧO/bbbzNۛvd@.ݷoϟpMMM\.~YfyF䪸ȳvڟ~Iv.\,~;&:z~s`cccRRRhnwo.֬Ycjjf|lNCC7|ӷo˗׷}ã-OMMݺ"rU\ɄUnnoӦMC19{ؙ&ࢨB$'' [md.tԾ'O .D(.@:{]...s:@7oիم|…Za XǏ| .dd2ҦLBv!@7ܹs<BGܹsdN:B={͛7kjj}&ILS{ IDATL166& f͚f\3!t͛7 HH>}Ǝ+(++{1ٳg_~kX:"11QUUU{?͞=b]vM tEbbمBp8III'O& f͚u zA(NI򪯯hdddkkKv!@ΙXZZ BG!ܼysr<'NLNNW[[ V&Lw!t_jj*Ñ0aB(55'@ȿ7o9wd#ցБpl$t*%%HBIIIqqޡŋ#G]^x ,&Lm۶W^v|бBHKKΎ*Bիd" P _`` %HjzzzC9>>Ϗ8m׮]6mz6ٵ(..B/B(>>B䄫Ç;>tBh,K~3+**222ğ=z46VG:!Իwooo?Bpvee対BqppxQCCCLJ t+444???//BtI&ijj]P8l6;??C:>dȐ( MmmmJJ [RXXX=|C:ZdӧG%&&Xӧ]PPvvv=B_rم̙3d]AAA:՝3gNdNyy /^Lv!@q 2oi'44K}2ɓdmmmmyy9rv\\\ &맓\cTUUɮ(. C[xq\\ܧO.DtϞ=[d مf``QRR·B߼yTLN1bСC.(4 2p@uuugϞ]`م PZZʷBd"Gl dqYYBN=zĈx:e݋/իٵ !t `pi_YYwߑ]!ddd;: 鱱d\.t$g``P__v!N455Ν{ak֬!KOO!TSSv!N-[VTTt ֮]GEv!N~ɍ7VZEv! BBCCϞ=[UUEv!۰aȑ#a UB|@ﯦ&.\a PSSSۅ:9rDO'oٲӓBhGYY!v!N7BCC矴4 Rnnŋ7nHv!hT*Bn :YO'o޼|҉NCXhh{ ă\~z s,F]=___MM͘ իlZfcgvx t6o޼(Cv-;w.55u߾} Zv`E.ҥK_xqm Wss?8w\GGGksu+͘1ct+**~7 K!mm !tz…CۓǏ7o 366&u:C@GWWWJN'o޼YUU.Z)##G~:ׯ: Ё+хz*992.]joo|rr[:h{:wΜ9sRiWVVfhhwKYȨРo>}СC/_L&ԬZjɒ%0R׭[Phh(m455IO.-gggUUU;;ϟ?ST˦&b&_lmؖ{فCv…Ç'@yi.PX,VBBرc̚>QnF}m߾wiĈ `٭@իW&&&| !t뛑rY,ߣY|aN͛7} N "S\\laaBG(ÇWRR7Iy޽X8@Q00E?}dnnηB9tдi:KJJ6lO?YYYItCƆo!B2d5)%ɓ鈈J 6ܑ]dڵk%5|%vSh4Zpp0Yȓϟ+++9ѩ]vظcH4tbbbܹpf.ad#Omll:@@>}455ێFR%:>|Xf͊+ &M(8ѣGΔQTGG[|(((:th:=cnn~M:λɒFI.t.\e BOB^ :.1xTr{:QQQ׮];y򤺺$?|𡬬ֶC:#}}l6=={8qHڜ9st:N={6ٵȉѣGw]\x1"czzz&M¥ALAAA5|p92#f[dooob6rӧ-q{O>Ji;Kw||-&5JB.ۣe޼ys]9|}}.g؋'Iy#ĉmfdd0n.8::u55)TjTTANNN~~~kk+I|R 77[!DFF}!dllZlB())H%Ν;Ӛ:=vر۷oR(-xDX<<>BHjjqRSS6C4pNйyҤI&R+0._u tl}||F{㰧wB =@;o߾W^mcc#!t\R__?""BB_/^oܸ!Dz€=~~~SLV t^SSsNn!;wX=*--o-Z-mAlvPP޽{ ^mۖ%VB=Zvv͛7n8bb*//'l:(iӦ;wNI3-pNիwjii]O:u9+++7 W(ׯ^:""b֬YoB`0fϞ|r# Bk.j@QN6166J%wB3f+..NYYJ򯦦fʔ)YYYzzzĉkkk322$=l0 tgXԤ]B:ȱZOO߾}[JdUuu)SJKKoݺ5h r!//A o=z_]?JffСCH:)Dž Lzybrb׮]gϞ1cƹs.KpԴ`ݻw\r˗/9B7Jnni j̙>LHH `*AEѪ\n6449lȞ?>k֬ʛ7o]PPP&&&cƌt*ڿ+W=ZYY9''GVAE$CҀb\rƌYYY2qO{:4mΜ9#ooCEFFFEE]Q@ť7ydv!F|TVVv) EGt:?dWlC\]])q!??V???kAEEEnnn+W OOO "AƎ?vXhiiYvy dWOAECh4󟖖R5jԁ<9x`R P\L&sK,qqqqqqYdL&ae455mڴՕNgff88m9so rÇڪaaa/_Ė|2,,LUUU[[;<<Ǐի{immP,o߾ TWWpuuuMMͰoJS԰0Mz@E eee==*ϯSVV z9^0p:>jԨ\:@=}4((NFFF nmmmdd!N z\zuڑ r<BȳӧSTcczک466RӧOm, !+*:@>eddL8!4hРflnn8qbff+//_ͥKƌ1bĥKl6x>1c\tIoޫW/CCØ܋E:@N옘aÆ!/]p$9s%GGGаa6pbbbLLLo.25&&!4}tA vgkkNMMuppPRR 22dFFFQ(ӧ߹sJ )#B0a;}t\m Wcc;V^˗/crHzʪ'\*ھxӧOJJJ!!!dWį8$$DIII__?""ӧOdW$] t(// RSSkaJ:aݸԴɮHZ@͛0 J+VeeeDDq ՞={uիWDDćȮH|ݸ={FvEdRɓ'شX:yűc _O555KK dggPER}||Sލ/_Μ9SGGb BHlTDnޞ7k566`k}d~?۷/J믿D655EEEƕ#Nk=ջQUUe``6d###%W"eo++\itVbb"BhРA◄]S3fLrrm ڰa˱-,,$X@ t).X܌9Sx6^K.1Dk0_-ǏB+ndb'N>|3\OOO 3f[V)..F8d:Jrvƌ#F8qk?MF@rX'Nϟ? #++S:'ꮯOJJ;wmBxzzfee1 cc۟8q7ٱ5Fa-B(88XkWX)SSSTFF.Zm 4ɓ' idd$ķ}ƍMMM%'BD7==-:\.h޽$MKK۷/B(<<ߖڒ7 VTTF:tH+B3txܹ9r$~ud؞3|hjj5j֭[\'ܹs!S @IIIXXJ>}"""%-B!_iTWWGDDGEE%,,D[ .q8nׯ_GHhc)--m+L[+t222B666_eeeٸJKKqOѣG---?rlѣG &`߿UQQ y5^-766&%%ukZL&355[˗,2>>~ %..\ׯCBBTTTtuu#""޿c|z7222Κ*ݶsssB/^YTT$~.:;;uJAIDAT{xxN722NKK*LQQ6W޽oNFW_J\vPAA6@^ú&ݻww=sY~D*څϟBׯ_'0 SؽQ2dF 8'_7. |yPP1O`B֭[NNN!Ǐ X622NURaa!a 22G'{ ݂x]r7n\VV׷ƕ'N1X)ccH)::`kk?\ |BXg#G&%%֍!4qD3'33}a``%1a]LL –!&L`0$T"UV }777nPb2tnn iMMM۷on#O:pԩƥ(ܮ0aĺ.[VTTZjd;d PX`ɓ' (.0te˖M2ٳg% 2݄Nccٳg ('''??!C|JvQLݏ_xj<)++ q8u-[TUU\~ӧE%ll;;aÆ:uJ5YrϞ=q '( =GѶlLBBvc1${:iӦh4\ZZ333}||6l؀ zvsO<9zR&M;v,NȈ=ճб^tMjjj$TNϟ?5jTuuuRRRjj E"""8κu$Q B^ 2dH~~3gx N޽|...f!. GD]yϞ=JJJwf Z[[?|@vE@>xxӧO󵴴B@$lm۶-]t͚5d P(Ǐ7668Xlٲɓ'?{%'}ݻwѣG]WA0ovvv/^Ɂ)v߾}{BB. UTTܻw/..pc1 ^ -Zɓ'&&&x5 ۷8p@[[{pc1ߧͅˮ䪫۵k9ڵkWXAvQ o \\\ L@]v555}aaaz"(s ^|8v3g"a7_eeUV^OvQ333s]xqǎ7:r-[6ugϞm߾H'Loׯ_Dd'''???[[[ltKuʕ_9s222$ `0\]]'M}x H? N/}᯾/˓VÇ'MNR FRRѣ. H0th4ɓ']\\BG$i9V\\;r>$%%]= A)++߃ >> i*B֭Qmɟ>}MC9sFszc͛6m搨EE$DztDMa|رfZr]=%iW>aaa؁^uuʁȮU<|L0̙3dW$Azzz!~Ǐ]BЉ FX!O:,`xl0l3g͛0`@nnnNN-33֭[FFF?=Q>'))iFFF!*l2;;***ƍ۽{7Bĉd@gؤ$]vU1&O.c dcO[IIIuuumw#G]tА!C.I8qbڴimblv-XNRIݻwB| م= &`00LPSSSfffۅ=ںuߍ9o޼YlYUUB1%%{=f9''gΜ9CmzKKKVVT1-,,fϞիW,\1nCɝqcW/ϟ?>566v[0w$wUƷ~>rlDIdй#| bNطo߾}.I@.A P:BA P:BA P:BA P:B9r/a@[EBBBhh(YHU (R20@A9 t B@>82̟IENDB`tins-1.32.1/examples/ones_difference-stm.png0000644000004100000410000011167414353307475021073 0ustar www-datawww-dataPNG  IHDR|4*bKGD IDATxw\3[MJ56JQQ * +ƨk&A7YM#1Xbcl[ (D myܽHٝ3|{YgyfBP ` w`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA .\x5U< t[l]B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B(B.]k.)))ѣm~,Y28UVK&9::2_.Mjj ˝5ksRPPuV~=H8:B0dRy<ޜ9sp+//۷o7₱*0DFFr\A 0G@̘1C.+p8X`322p8666`TDD A:Q!P(t `TnFI ]B0mΜ9 bݺu] @7} H&<~x `۶m;xzBB(p0܅@O˵/'AKo{:FA`Q:FA`Q:FA`Q:FA(SPP}3guUěCBBN>M_Pm%@ɓ'{I_U[[̗}=x>ضm=E `@ (Ya\4rСC{#c@&@zB t/++C 06:uWZeooqFܵA&uk,}}CY@@Q(K,A.BKLLˉ'֯_@ .;v "::֭[ԃxↆ3f.P BP.%%jhhx"3g/ݻ7k֬ VM;otl+ (cddݷmk``zԨQ&M:z(y5bĈ#G9rUC:2ꫂr9eQ "FMpy`Q:FA`Q:FA`Q:FA`Q:FA`端ںuk_P455|jsss_4k/ʕ+=zԥܽ{cƌr*̙3*׭[׭[7B(!!a{9sj-[nŊpJ_W{y.]r 233 xc( t@UWW2.%%Sݓ'O\;w޶G 2]##""$ɁI'O d2蚯Ӈѣ:V?N]p5klذaСj6ɯe2۷?v@=YyyyC 6mږ-[o- \.o߾7n܀;;ZBtJmm lM*444'Ǝf t/^=zTAݹsux/BA耎[ vvv4xORiVVVrr2%:p>,&&& 6/_y<ի: `'SPP0x]vQج[~~oVV)<`VuuuA\xАfuP(|>AMMM䇐yxx$%%Qx86x geeQzzz...'Oζiz:m%KN<9zhZt)SH$ZXamHKKDN@ P(th,,,lҤI?8P(D2p,: ӦMܹs'33ufnncn$7|'411a:vܹiӦ#Gxzz2y\@; %++룏>ZjդI>P(+BŋSN1bė_~ѡS td|>2ccc# ttWUUɓ vZܵ '''%###ܾ*Bz:: `An_uyܵ @ ]`tt}ƍ߾*0TGw@蜼ٳgϟ?kPX\\,qh[jkkLҧOw-oeee ! "22ŋ -}YWXBG[رcj* Cxz+N>vZܵP=-$J}~A~AA̙3#"">c`hϧ]|ygʔ)Bp͸Kk:Z~xR4))O>/))|* /BGH$#GHRPSSSIIIII'|B>b3@PTTP(Ytd2LwEGGd2uH ={ w!^:fmvWWW3_R'X:BG;v\.?+$O͵V?nN Yf}gY<z:Zn$kݻw r{}aÆa`.xYjjjk+>;w?ql=Am6wwwUu@ ~:*=C{x;w}ւUl̬[np[Gk)@' 8k?nkk<66UKEEEmmszںuj4jAٚU() thaCCׯ5 !iӦNhזFFFAAAoUl 6b:;r}||lmmcccB4z5Qڷ O͵v9n8k777B F t6BGAnРA\.!rkV߸q#5Qڷ) ) v- .\iii|?tМ"|]"r9 J:Ϗݳg /W(K,AR]e|$r| \ai%444\2 @Fbbb\\\N8~z k%o!diiijj CD"ʕ+B BFwADtt[MKV:Lضmٳg7 rɑ,* ZxqCCÌ3ꨭSMM thx\ \ f͚6_pE3g466^dݻwo֬Ys"6mv,奭 th7uT2,8Ό3 6_k``3jԨ0"ȑ#NNNTey]Kyi+˜vxRedPP\.W,9̺5@PZZ*Jyyw!J:`,^OOnh^z:ZB >:੹} tWo[Wh"j@"<w!2:?}tB LLLpV>dҽ/RYYzjZ҂rrvrppr?@TZZ: >Ro,a9\.KIGKA0- e2X,Rf!h:y{{7 ~qY`a8p`@7K`)/MᆱG~p<=='M$ 5Ea Nޒ4@ (** *ߟLhxx84P(lhhx)B t0puuEzj\%aZvvvvvvPPB2""wEޞýdÜc\r!m``. r!t4N:XVVo߾}IRБ#GOixj th$Jwݷo߱cǚݼy3<<<<<޽{iiicƌ۷ݻO5-ׯ_>wܞ={'%%X+gذaIII/^ٳܹsׯ____f 5P6&&G\.7""͛y͛7#""\n=bbbjkkSرw@E:VVV|>?***??-EEE|+++X\YYIGZ 55!s܅U@PL$DǏǏE"H$*//Nz*B* tR\\,bӧOjӧbX$Sղhllr]P>>wdKc@ ]2VbTeOO9s8;;edd5 w]m5jԥKҜ̙e]`i0wYD" B BCC_~zhh(AB066V"ஈFuuuA=zw! t Z,x[nuGm۶mƌU i]t-rX,iQ;ҼܹC߁lmmׯ_O_&: S"H S$//Юv%ə3gW|hΝ666WB/ƕwUUUEGG#|||;СC>9aH$ߦjW_uiD"###rWYY vh͚5r\Pz !dmmM߱O>uT4)**׷Ϟ=eBԢgϞb rOQQ%ͶI٥z;g}6p@4ѭɉݻwcT?lذ.!jFUWWXZZ oi̙\v?leeE!t%t9}ӧO˔WHNrppp8׮] b䛊hhh W^>ΥK pwwB˫<<55!'P۸ҝ;wB> tə0aA={_>tjjjrrr֯_okkkaaNCSWWyfr\ĉ)_7c!jUA?~M9t>3CfHՍ/R~OmΟ?occJ6׽{͛7>6OoA``2+!t}P( $ jANӧ6`i"mrV+W¼4bVdvv6ݔ#w LKK# |.˗B-`,Ŝ4򎲋Kll,x$Irrr~~~mܹs RӧO<(ؿ?*XqZZ+ WW)S<|077XA,_חt(tH7n &9;;S8+4 |)SΟ?OIaXgggr7l onҥFFFܴiL&@.MvlsCsNDDdz/_]]^|)ɹZѣA.t@$EGGWTTஈJfff"wEԻqB6,::'ODGGDD95::ɓ'+˗/BO]<\,w֍a*77wE%w֭X,օwͷlق :oxyoy}uֽ{ȹvvv3#W]mSSe˖gϞӧτ pr}={~]l)BhfPK IDAT6/[,??Ν>D(Yݵ֬Y# k%$$丸 2d˖-B8;;COG(%i\S媵S^^.LMM [OJbDDDh]2vعst>}*̌:X$O7-,,|||=zDE?1b*@gAPehhHΥxa^x!>|د_ݻ:u5ط~₻ Y:8qA+W#Gܻwݽ{744WMM {,۷oϗJ CcǾ{ >..ɉʕ+/dff999ũvj\\u:ud@!ݿ G*"H6l@Fϔ)SLp7lؠഴ4;;;77[nٔ*--Eѱ3,Ya{ݻ)kӧ#F044ܹs'Umj\n``g܅NQ]LLL֮]p1MMM(ZNf'ww wS`p v܉?>x111{GY^^px\s C%\iӦH ,̘1#+++55K X@h*?~ѣG˖-(ěZ^zeff~}lA tnܸq /&$$|WW9sfmm-P($.t BkZmo۷E"B4:hР㮈^ӧ С͛===Ǎyw}}}> B:Ԩܽ{EضçMrJL"Z888| tc7o<܅A__?..n׮]6l=zgpWD=.=:mKLiӦ9syYǏ4ʕ+ˡ<5:HJJ*..^t)B:s޽{nݺw9 46l0fwww܅t{'OFFFᮈ2:uٳgQ"'&&;vlذaZ;:ڴiS^>܅t\"J tiP@(~w!:jسgϒ%K3233'N8nܸ5kr6:jٶmޜ9sp";vl޼o d\5 tT'J7op&.?=͛7oԨQ ^HHHfffEEŠA]4, tTӽ{~G ˗4hA@PUUU]]Ul۶$22w!4255=xڵk͚5K#$AtYSSw-"bٲe)))gΜ]QA:,eӧOIygeee 0ȑ#i a9.۸qĉɞptt %NlܸqРAÇ]{EEE߼yԜ t:VZZ;T6hР,r*z:,ӱ8KK3f.DXYYZ~B t:P__믿.X@__w-=zFz z : BZhB4ĉ\B.?x%&- Eqq1Bxeiiу޷o9vSN]  drKy)X = &333AGedd.JX>O.?A̶ṉ@WAO r!P(*++wMW_}'UeAf:on.MMM ӣG4hPbb"4Z``rG}86yCeeeJRЍ72 .,Zhʔ)t/?` AIIIDf~ƍ'LK`:\.f4k֬ Z3.yCee%τ$$$t~wUUU 0`…/d2YiizeZ@輡kX͛CBBԣ5k,X@B1c͛7lr)':wm濺m;vС/"99Y.s89s樼Ja'] +W̟??>>5˗/ϧ83^n;vlFFF]]kL/_\zjm\XXι`ȼgώ5 !dooOP(ܼys]]̙rB\.722R.cV\vM__A TkpРANNNkNT*߿?B/99YPD"ݻ⊊ BnCCuׯ===[MxoCn nfaaH$222211D!___D`s\ru\V@Ǵ6t$Ill@ "44gbAfffٌ >vZP\GEEQ@0tb Nj}v'_X]]b KKK>Ckt??? Z_aYm_S\t5*t***bq D"ѣGThױ'888++:AkcǎWp87onp5NiiH$211122Dj6NDppK(tqqqAx<q##bkͧSTToaa!={Fa㍍B( 11Arss>}WX>εй~DDϷ}MdlODä{-Y\ѱGp5FNVVVpp0qpp}53MKK{BJW5?}k-as%rH{||<{iiiBFkpƄNbbb@@Bw9xL&[ύ7"""8@ s:r>>>'&&b6w툈gcc#pW\9_~#G<="EGGԞsS:... 6{IttrjOii)4kĮ!'8;;s܈7nந˞?"E}}=NYl /_bkkkr͝;wBAAAHHۺu:?dCCCwwsfffv ҫWbccmmmɩ=W6G 84&Ċh333rMAA <ֶ)66H$gΜ!_˺;wp8]zHGGGrjիWUn/^ %k\ӧB%%%I4O},,,._LGiii#GDDa&Mj~㣏>bx"h= Ça:IOO'=<<D_®~Q+wޥH9 X*dEEE۷o'ׅ@mܸ;mh: "44t޽zpD{g&u֭ 333SByjjjrrr֯_okkkaaNCoHKK;v,yC–'Nzw(lm\ws}U')Cf{ B.zW\INTH$:tPUUH$IR [=B(??f纫(9+WoZv [^^^TTdz􍎍0arŋm?ZU9fС4k@ 6n}k1W\AAH$244455DԶuVwwwrL&ۺuw_T#z.L.tO8JNNFZCZs!1]ӧObH$Fzz^kΝ;G@*>}>J理Bbcc{IoygXXXAAjkk8P\3pi9S[nzzzo-#8NO_PPPm5SL9)уxMZnmʕzzzz/n sNjjjbcc8Nhh(,qVVV|>?***//wEJs>..ɉ)d_*//D"Us l됧'B( %%wEj)..Dbӧ+b8:-C" 8w:r~X,ң\Zg+tHr<11!)ݽ{744HAl %C}cU233i5NNNqqq+oee%++++DN!kOMs[aC ȩ=eee | -B06T<~4.ϵƥ)4,td2ٚ5k\nhhh^^X,677'TCP($"44r|̘1\.Rƅ\t ]ISRR2|p##xcbb,--ɩ=ž<׀*4GGG@¿cԞANLQNݻ:q8ղ ;׀ _~?BBo=ڵkM*Oټys;|>ۻTAW1pX: B"̘1P5K95..{777wh &#055򲳳!k\? @n\} 2___ 'NPٳgɭlll >7odϭ#wSSSrb1 g\ۓ䧟~]`Ydgg BWW۷ow==QFڵA4IIIApܐ􂃃 Eff%Ks=t˗)tN8ajj:rH5o⴯ !t!:_jՐ!C?YYY={tssx͚5kĉ4yk֬?~9sOKKK$HBt47dffZYY5322 q\nnnyyyHҨ/~ڸqM122(-ڦ,X 44R;ѣGL} Ѵ̨3gNbbݻg͚ di鴃C {nח9::EzjرɧOf&q!M>̙3/^/**RrssCvBѣG.] dX.p8~~~W^U155]:Çd/^$'0oOx…ݻc%ڭ:a۷o>G  211?"###""6oތ؀w=z۱c,,,>:BH"p\Ϗ[xqEE"ziU:FC#Gӧϱcp5jkk Mk֬qqq?~~~mY.؀+W>rGlqIO~mBddyxxxUU \-Nzo ۫Wȉr=+WÇg,qPJ$BhҤI'O<{qjjjpZߺ"xj=nܸ߿yZv{wSSSܹ{=w9=trrrF흘Ȇ,R8p`JJJiiiHHׯq8NϞ=#G;))%oyyԿ3g?|=h O=֖=X|y;拉=﨣͉ ;B&88:ǔ͗WJgϞ}رc:Zpy-^\\Ķg,RHMMχܡϫqh ?0--ɓt_^)?ətݻw:tLJէWJ?vؕ+WfϞ OQB(x<(?OmTH$! :رc'NOqע |3iW\7oއ~((lZ! >;v̚5k<#{:/^ܰaƍY8mJiƌs΍zZ4l SSS1eʔHj v\^)ϮMMMk00#C>H$ Mk.HѸk0X:g\\ƍY>*ZlzEGG-[;v w-M*vXt9tϟ?m4xFނD"aT:uY.\˹wl QCocЉW矹\.ٲUXc?ӆ lmmi*Z bŊ]ׯ_ojj_9Nn|IZlϦv5jԨSN6 w9TTTobbsNrhУXExۼϞ=v˥& ZXXr \P(R)B(11q„ Xk󓒒޽˶%bYq999Hnp5_Sօ˫ǏlڴIS!dllCUhhرc,X@v@ |=S#H>ɉ(ЧO?7nmyyy7n+Vh\ccA::D"Yr%dԩzzz,XA7:mҥk֬] -_w:8t tޝ0q?dqCիW#bbbpF+Wl `w%mllo׺uqF_T~8NHHtH=Tw͙3G& K*j-/^_.);;pig޽{y<ޣG@8qB!am˖-qPWWףGxSNHtYnԩS{Ic1#z-XPb޼y={;;m200ЁȌj'222BE &L@Akaȯ_ZZ6'oE_|||?M2EP{**sε]7!̴QMMц hͼ^z^VVt¢w!׿L?[om>|\?˗3OM]]3x8coҥ}opBܵtك|}}.b֭]6o {͇3744, 3fl޼YC!}%=/^3\ ŋoݺz[$%%qܐt)%:#FuӢE>} 3_ -,,v؁ ̚\kFgϝ;_ms=3F;wY >.\XRR|X:.\иA\\\ƌv-CG.gff>K5V-:uTnn.BNk:>|,/Ǝk.܅2t_ׯ_?,Zqܹsڵ n'Zݻw=<\SSZNAA R3e2١Cpt#HpUDh"kkkKKŋ744t999~5W( &M 9~t-88Xwh#Gu}̙%%%+<{ !|( HMM%bȑ/_ܻwo'_)pe˖6wIɓ'¸su>!aÆfgg.x!dmm.pBRRҒ%K߯_K۷ڵk|y}}=Q8 秦8qYYYi߽Q~bo?YPPn:uyBS1]FޘxoGڿ?ΚP(Mի{S&W(4ZZ !G?(8=:Ul?!J~K~|J@@@gt$''ԔUwʕe˖9::R3rssoݺEa,'$###$$VOO{l[o.B!:Nyy9B[nd픔dddxyy}7l{C^ۛv}}}>~Sl'D$]p!33իW۶m;p@TTMOoNSSBc*^|200 %㲲R iiiiii|rЦMhUU Dr…ׯ744޽[f 4iSUYY) &M:wwUg}×/_O!j;Ŕ`[a#?LRV" Iq\/B޽{T6ʕ+-,,z"~[4iҭ[=z~SE'jӦMB}O={_QQ1`3grP`` ڣ١RB Z# SE QΆ#?O>T堠 KKK J~CzzΝ;i*RM~iiiׯO?~x5?!VZv}y{{T$Uۗ2z蠠 ܵGC'""!J~={j]z!4}tBǎ#>Bh̘14>iҤ'OP ٶmB?D566R"EN<9o w}ɓ'4K+ ~SL<7Ay :tڴi}{l=pW H{:Ak˖-FFF(GaU}ut&LPWWיLPBG0hĈlh @#Fq9pAP(`@+,  !4bĈlr!hBhذa/.h?Bݺultq* ~?>uԼyvE"B\/;;w!B"ܹ׭[wersbmm CAS]]}ĉUV-\pEEE+oo7oB'888,]\D.*w9w\P}!tx{{CO1k׮ms&rti̡O.eB&&&xlUп\@dR/!!ؘ'&&у|3ɵI1+,,l~~~ X?+nnn2X7^_ĉ97&+FLJJd /abbafagpLQ$tɒ@{۶mV9-|VVV X[ٳ?#|7|?;kggBUX___ 7l_-Z: By|>fff^=**ի ܲe ) WX8::>| +W?ݻ˗?EM2ŋxxt0 { ?׏9|pZZڀ` xwqM]Ož*ą nQjZV՟uઢb*ֽ D@PCe>O BHn%7~3p9۷dW :.zѐ!C<<<|pSN]N7 t? "['&BHKK'AHOH!Xv@>>wss=rH aڵׯ_"CSlmmLgqQ\pB ,,,%%@ tWQQ葩SZ[[Bb#QrJt ߄SԄ֕ëg"Ə8n8P\\ bs!p3k֬KSSSM&fIII}!oW_}%Zs,ͱ0f777,++CIT|m;FݸqIGGGfǏ/m#HAu&cٲe?2:!===GfeݺuFFFx "!ϟ5k0L1qD\JNgʔ)Ǐ2:>}Bb?bKTWW󞐑`0mBXTT$G,^^^b4i$\N 7A e111="&á, /{X!˥hIMM4h$''[ZZJKPGGx ]Y`A]]ŋ{ NB>m۷8ڵk{űBܝ?~̙ⷓ$VH!&t`ԩ! 6˗/>}3fMihh?~BөD\ŋ?SUUCEzt 7+ .LNN.--~ Э[(D_ߟdU$rssutt,--l'--B}?OEzt 7SӧO/bbbzNۛvd@.ݷoϟpMMM\.~YfyF䪸ȳvڟ~Iv.\,~;&:z~s`cccRRRhnwo.֬Ycjjf|lNCC7|ӷo˗׷}ã-OMMݺ"rU\ɄUnnoӦMC19{ؙ&ࢨB$'' [md.tԾ'O .D(.@:{]...s:@7oիم|…Za XǏ| .dd2ҦLBv!@7ܹs<BGܹsdN:B={͛7kjj}&ILS{ IDATL166& f͚f\3!t͛7 HH>}Ǝ+(++{1ٳg_~kX:"11QUUU{?͞=b]vM tEbbمBp8III'O& f͚u zA(NI򪯯hdddkkKv!@ΙXZZ BG!ܼysr<'NLNNW[[ V&Lw!t_jj*Ñ0aB(55'@ȿ7o9wd#ցБpl$t*%%HBIIIqqޡŋ#G]^x ,&Lm۶W^v|бBHKKΎ*Bիd" P _`` %HjzzzC9>>Ϗ8m׮]6mz6ٵ(..B/B(>>B䄫Ç;>tBh,K~3+**222ğ=z46VG:!Իwooo?Bpvee対BqppxQCCCLJ t+444???//BtI&ijj]P8l6;??C:>dȐ( MmmmJJ [RXXX=|C:ZdӧG%&&Xӧ]PPvvv=B_rم̙3d]AAA:՝3gNdNyy /^Lv!@q 2oi'44K}2ɓdmmmmyy9rv\\\ &맓\cTUUɮ(. C[xq\\ܧO.DtϞ=[d مf``QRR·B߼yTLN1bСC.(4 2p@uuugϞ]`م PZZʷBd"Gl dqYYBN=zĈx:e݋/իٵ !t `pi_YYwߑ]!ddd;: 鱱d\.t$g``P__v!N455Ν{ak֬!KOO!TSSv!N-[VTTt ֮]GEv!N~ɍ7VZEv! BBCCϞ=[UUEv!۰aȑ#a UB|@ﯦ&.\a PSSSۅ:9rDO'oٲӓBhGYY!v!N7BCC矴4 Rnnŋ7nHv!hT*Bn :YO'o޼|҉NCXhh{ ă\~z s,F]=___MM͘ իlZfcgvx t6o޼(Cv-;w.55u߾} Zv`E.ҥK_xqm Wss?8w\GGGksu+͘1ct+**~7 K!mm !tz…CۓǏ7o 366&u:C@GWWWJN'o޼YUU.Z)##G~:ׯ: Ё+хz*992.]joo|rr[:h{:wΜ9sRiWVVfhhwKYȨРo>}СC/_L&ԬZjɒ%0R׭[Phh(m455IO.-gggUUU;;ϟ?ST˦&b&_lmؖ{فCv…Ç'@yi.PX,VBBرc̚>QnF}m߾wiĈ `٭@իW&&&| !t뛑rY,ߣY|aN͛7} N "S\\laaBG(ÇWRR7Iy޽X8@Q00E?}dnnηB9tдi:KJJ6lO?YYYItCƆo!B2d5)%ɓ鈈J 6ܑ]dڵk%5|%vSh4Zpp0Yȓϟ+++9ѩ]vظcH4tbbbܹpf.ad#Omll:@@>}455ێFR%:>|Xf͊+ &M(8ѣGΔQTGG[|(((:th:=cnn~M:λɒFI.t.\e BOB^ :.1xTr{:QQQ׮];y򤺺$?|𡬬ֶC:#}}l6=={8qHڜ9st:N={6ٵȉѣGw]\x1"czzz&M¥ALAAA5|p92#f[dooob6rӧ-q{O>Ji;Kw||-&5JB.ۣe޼ys]9|}}.g؋'Iy#ĉmfdd0n.8::u55)TjTTANNN~~~kk+I|R 77[!DFF}!dllZlB())H%Ν;Ӛ:=vر۷oR(-xDX<<>BHjjqRSS6C4pNйyҤI&R+0._u tl}||F{㰧wB =@;o߾W^mcc#!t\R__?""BB_/^oܸ!Dz€=~~~SLV t^SSsNn!;wX=*--o-Z-mAlvPP޽{ ^mۖ%VB=Zvv͛7n8bb*//'l:(iӦ;wNI3-pNիwjii]O:u9+++7 W(ׯ^:""b֬YoB`0fϞ|r# Bk.j@QN6166J%wB3f+..NYYJ򯦦fʔ)YYYzzzĉkkk322$=l0 tgXԤ]B:ȱZOO߾}[JdUuu)SJKKoݺ5h r!//A o=z_]?JffСCH:)Dž Lzybrb׮]gϞ1cƹs.KpԴ`ݻw\r˗/9B7Jnni j̙>LHH `*AEѪ\n6449lȞ?>k֬ʛ7o]PPP&&&cƌt*ڿ+W=ZYY9''GVAE$CҀb\rƌYYY2qO{:4mΜ9#ooCEFFFEE]Q@ť7ydv!F|TVVv) EGt:?dWlC\]])q!??V???kAEEEnnn+W OOO "AƎ?vXhiiYvy dWOAECh4󟖖R5jԁ<9x`R P\L&sK,qqqqqqYdL&ae455mڴՕNgff88m9so rÇڪaaa/_Ė|2,,LUUU[[;<<Ǐի{immP,o߾ TWWpuuuMMͰoJS԰0Mz@E eee==*ϯSVV z9^0p:>jԨ\:@=}4((NFFF nmmmdd!N z\zuڑ r<BȳӧSTcczک466RӧOm, !+*:@>eddL8!4hРflnn8qbff+//_ͥKƌ1bĥKl6x>1c\tIoޫW/CCØ܋E:@N옘aÆ!/]p$9s%GGGаa6pbbbLLLo.25&&!4}tA vgkkNMMuppPRR 22dFFFQ(ӧ߹sJ )#B0a;}t\m Wcc;V^˗/crHzʪ'\*ھxӧOJJJ!!!dWį8$$DIII__?""ӧOdW$] t(// RSSkaJ:aݸԴɮHZ@͛0 J+VeeeDDq ՞={uիWDDćȮH|ݸ={FvEdRɓ'شX:yűc _O555KK dggPER}||Sލ/_Μ9SGGb BHlTDnޞ7k566`k}d~?۷/J믿D655EEEƕ#Nk=ջQUUe``6d###%W"eo++\itVbb"BhРA◄]S3fLrrm ڰa˱-,,$X@ t).X܌9Sx6^K.1Dk0_-ǏB+ndb'N>|3\OOO 3f[V)..F8d:Jrvƌ#F8qk?MF@rX'Nϟ? #++S:'ꮯOJJ;wmBxzzfee1 cc۟8q7ٱ5Fa-B(88XkWX)SSSTFF.Zm 4ɓ' idd$ķ}ƍMMM%'BD7==-:\.h޽$MKK۷/B(<<ߖڒ7 VTTF:tH+B3txܹ9r$~ud؞3|hjj5j֭[\'ܹs!S @IIIXXJ>}"""%-B!_iTWWGDDGEE%,,D[ .q8nׯ_GHhc)--m+L[+t222B666_eeeٸJKKqOѣG---?rlѣG &`߿UQQ y5^-766&%%ukZL&355[˗,2>>~ %..\ׯCBBTTTtuu#""޿c|z7222Κ*ݶsssB/^YTT$~.:;;uJAIDAT{xxN722NKK*LQQ6W޽oNFW_J\vPAA6@^ú&ݻww=sY~D*څϟBׯ_'0 SؽQ2dF 8'_7. |yPP1O`B֭[NNN!Ǐ X622NURaa!a 22G'{ ݂x]r7n\VV׷ƕ'N1X)ccH)::`kk?\ |BXg#G&%%֍!4qD3'33}a``%1a]LL –!&L`0$T"UV }777nPb2tnn iMMM۷on#O:pԩƥ(ܮ0aĺ.[VTTZjd;d PX`ɓ' (.0te˖M2ٳg% 2݄Nccٳg ('''??!C|JvQLݏ_xj<)++ q8u-[TUU\~ӧE%ll;;aÆ:uJ5YrϞ=q '( =GѶlLBBvc1${:iӦh4\ZZ333}||6l؀ zvsO<9zR&M;v,NȈ=ճб^tMjjj$TNϟ?5jTuuuRRRjj E"""8κu$Q B^ 2dH~~3gx N޽|...f!. GD]yϞ=JJJwf Z[[?|@vE@>xxӧO󵴴B@$lm۶-]t͚5d P(Ǐ7668Xlٲɓ'?{%'}ݻwѣG]WA0ovvv/^Ɂ)v߾}{BB. UTTܻw/..pc1 ^ -Zɓ'&&&x5 ۷8p@[[{pc1ߧͅˮ䪫۵k9ڵkWXAvQ o \\\ L@]v555}aaaz"(s ^|8v3g"a7_eeUV^OvQ333s]xqǎ7:r-[6ugϞm߾H'Loׯ_Dd'''???[[[ltKuʕ_9s222$ `0\]]'M}x H? N/}᯾/˓VÇ'MNR FRRѣ. H0th4ɓ']\\BG$i9V\\;r>$%%]= A)++߃ >> i*B֭Qmɟ>}MC9sFszc͛6m搨EE$DztDMa|رfZr]=%iW>aaa؁^uuʁȮU<|L0̙3dW$Azzz!~Ǐ]BЉ FX!O:,`xl0l3g͛0`@nnnNN-33֭[FFF?=Q>'))iFFF!*l2;;***ƍ۽{7Bĉd@gؤ$]vU1&O.c dcO[IIIuuumw#G]tА!C.I8qbڴimblv-XNRIݻwB| م= &`00LPSSSfffۅ=ںuߍ9o޼YlYUUB1%%{=f9''gΜ9CmzKKKVVT1-,,fϞիW,\1nCɝqcW/ϟ?>566v[0w$wUƷ~>rlDIdй#| bNطo߾}.I@.A P:BA P:BA P:BA P:B9r/a@[EBBBhh(YHU (R20@A9 t B@>82̟IENDB`tins-1.32.1/examples/minsky.rb0000755000004100000410000000564214353307475016305 0ustar www-datawww-data#!/usr/bin/env ruby require 'tins' # A small Minsky (register) machine module Minsky class InterpreterError < StandardError; end class ::Proc attr_accessor :interpreter attr_accessor :name def execute interpreter.display_registers(self) call end end class Registers def initialize @registers = Hash.new(0) end def [](name) @registers[name] end def []=(name, value) @registers[name] = value end def to_s "[" + @registers.sort_by { |r,| r.to_s }.map { |r,v| "#{r}: #{v}" } * "|" + "]" end def method_missing(name, value) name = name.to_s if name[-1] == ?= name = name[0..-2].intern value >= 0 or raise InterpreterError, "only non-negative numbers can be stored in register #{name}" @registers[name] = value else super end end end class Interpreter include Tins::Interpreter extend Tins::ConstantMaker def initialize(source) @source = source @labels = [] @registers = Registers.new end attr_writer :stepping def run interpret_with_binding(@source, binding) cont = @labels.first while cont cont = cont.execute end self end def display_registers(label) @format ||= "%#{@labels.map { |l| l.name.to_s.size }.max}s" STDOUT.puts "#{@format % label.name}: #{@registers}" if @stepping STDOUT.print "? " STDOUT.flush STDIN.gets end end private def label(name, &block) @labels.find { |l| l.name == name } and raise InterpreterError, "label named '#{name}' was already defined" block.interpreter, block.name = self, name @labels << block end def register_fetch(register) @registers[register] end def register_decrement(register) @registers[register] -= 1 end def register_increment(register) @registers[register] += 1 end def label_fetch(name) label = @labels.find { |l| l.name == name } label or raise InterpreterError, "label named '#{name}' was not defined" end def increment(register, label) label = label_fetch label register_increment(register) label end def decrement(register, zero_label, else_label) register_value = register_fetch register zero_label = label_fetch zero_label else_label = label_fetch else_label if register_value.zero? zero_label else register_decrement(register) else_label end end def register @registers end def halt STDOUT.puts " *** machine halted" nil end end end if $0 == __FILE__ if ARGV.empty? Minsky::Interpreter.new(STDIN.read).run else interpreter = Minsky::Interpreter.new(File.read(ARGV.shift)) interpreter.stepping = !ARGV.empty? interpreter.run end end tins-1.32.1/examples/let.rb0000755000004100000410000000245314353307475015554 0ustar www-datawww-data#!/usr/bin/env ruby require 'tins' LetScope = Tins::BlankSlate.with :instance_eval, :to_s, :inspect, :extend class LetScope include Tins::MethodMissingDelegator::DelegatorModule include Tins::BlockSelf def initialize(my_self, bindings = {}, outer_scope = nil) super(my_self) @outer_scope = outer_scope @bindings = bindings extend Tins::Eigenclass eigenclass_eval { extend Tins::Constant } each_binding do |name, value| eigenclass_eval { constant name, value } end end def each_binding(&block) if @outer_scope @outer_scope.each_binding(&block) end @bindings.each(&block) end def let(bindings = {}, &block) ls = LetScope.new(block_self(&block), bindings, self) ls.instance_eval(&block) end # Including this module into your current namespace defines the let method. module Include include Tins::BlockSelf def let(bindings = {}, &block) ls = LetScope.new(block_self(&block), bindings) ls.instance_eval(&block) end end end if $0 == __FILE__ class Foo include LetScope::Include def twice(x) 2 * x end def test let x: 1, y: twice(1) do let z: twice(x) do puts "#{x} * #{y} == #{z} # => #{x * y == twice(x)}" end end end end Foo.new.test end tins-1.32.1/examples/null_pattern.rb0000755000004100000410000000153414353307475017476 0ustar www-datawww-data#!/usr/bin/env ruby require 'tins' $:.unshift 'examples' include Tins::Deflect puts "Example 1" deflect(NilClass, :method_missing, Deflector.new { nil }) do begin p "foo".bar.baz rescue NoMethodError p "caught 1" end p nil.bar.baz t = Thread.new do begin p nil.bar.baz rescue NoMethodError p "caught 2" end end t.join if t.alive? p nil.bar.baz end begin p nil.bar.baz rescue NoMethodError p "caught 3" end puts "-" * 70, "Example 2" deflect_start(NilClass, :method_missing, Deflector.new { nil }) begin p "foo".bar.baz rescue NoMethodError p "caught 1" end p nil.bar.baz t = Thread.new do begin p nil.bar.baz rescue NoMethodError p "caught 2" end end t.join if t.alive? p nil.bar.baz deflect_stop(NilClass, :method_missing) begin p nil.bar.baz rescue NoMethodError p "caught 3" end tins-1.32.1/examples/ones_difference-mtm.png0000644000004100000410000011167414353307475021065 0ustar www-datawww-dataPNG  IHDR|4*bKGD IDATxw\3[MJ56JQQ * +ƨk&A7YM#1Xbcl[ (D myܽHٝ3|{YgyfBP ` w`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA .\x5U< t[l]B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B(B.]k.)))ѣm~,Y28UVK&9::2_.Mjj ˝5ksRPPuV~=H8:B0dRy<ޜ9sp+//۷o7₱*0DFFr\A 0G@̘1C.+p8X`322p8666`TDD A:Q!P(t `TnFI ]B0mΜ9 bݺu] @7} H&<~x `۶m;xzBB(p0܅@O˵/'AKo{:FA`Q:FA`Q:FA`Q:FA(SPP}3guUěCBBN>M_Pm%@ɓ'{I_U[[̗}=x>ضm=E `@ (Ya\4rСC{#c@&@zB t/++C 06:uWZeooqFܵA&uk,}}CY@@Q(K,A.BKLLˉ'֯_@ .;v "::֭[ԃxↆ3f.P BP.%%jhhx"3g/ݻ7k֬ VM;otl+ (cddݷmk``zԨQ&M:z(y5bĈ#G9rUC:2ꫂr9eQ "FMpy`Q:FA`Q:FA`Q:FA`Q:FA`端ںuk_P455|jsss_4k/ʕ+=zԥܽ{cƌr*̙3*׭[׭[7B(!!a{9sj-[nŊpJ_W{y.]r 233 xc( t@UWW2.%%Sݓ'O\;w޶G 2]##""$ɁI'O d2蚯Ӈѣ:V?N]p5klذaСj6ɯe2۷?v@=YyyyC 6mږ-[o- \.o߾7n܀;;ZBtJmm lM*444'Ǝf t/^=zTAݹsux/BA耎[ vvv4xORiVVVrr2%:p>,&&& 6/_y<ի: `'SPP0x]vQج[~~oVV)<`VuuuA\xАfuP(|>AMMM䇐yxx$%%Qx86x geeQzzz...'Oζiz:m%KN<9zhZt)SH$ZXamHKKDN@ P(th,,,lҤI?8P(D2p,: ӦMܹs'33ufnncn$7|'411a:vܹiӦ#Gxzz2y\@; %++룏>ZjդI>P(+BŋSN1bė_~ѡS td|>2ccc# ttWUUɓ vZܵ '''%###ܾ*Bz:: `An_uyܵ @ ]`tt}ƍ߾*0TGw@蜼ٳgϟ?kPX\\,qh[jkkLҧOw-oeee ! "22ŋ -}YWXBG[رcj* Cxz+N>vZܵP=-$J}~A~AA̙3#"">c`hϧ]|ygʔ)Bp͸Kk:Z~xR4))O>/))|* /BGH$#GHRPSSSIIIII'|B>b3@PTTP(Ytd2LwEGGd2uH ={ w!^:fmvWWW3_R'X:BG;v\.?+$O͵V?nN Yf}gY<z:Zn$kݻw r{}aÆa`.xYjjjk+>;w?ql=Am6wwwUu@ ~:*=C{x;w}ւUl̬[np[Gk)@' 8k?nkk<66UKEEEmmszںuj4jAٚU() thaCCׯ5 !iӦNhזFFFAAAoUl 6b:;r}||lmmcccB4z5Qڷ O͵v9n8k777B F t6BGAnРA\.!rkV߸q#5Qڷ) ) v- .\iii|?tМ"|]"r9 J:Ϗݳg /W(K,AR]e|$r| \ai%444\2 @Fbbb\\\N8~z k%o!diiijj CD"ʕ+B BFwADtt[MKV:Lضmٳg7 rɑ,* ZxqCCÌ3ꨭSMM thx\ \ f͚6_pE3g466^dݻwo֬Ys"6mv,奭 th7uT2,8Ό3 6_k``3jԨ0"ȑ#NNNTey]Kyi+˜vxRedPP\.W,9̺5@PZZ*Jyyw!J:`,^OOnh^z:ZB >:੹} tWo[Wh"j@"<w!2:?}tB LLLpV>dҽ/RYYzjZ҂rrvrppr?@TZZ: >Ro,a9\.KIGKA0- e2X,Rf!h:y{{7 ~qY`a8p`@7K`)/MᆱG~p<=='M$ 5Ea Nޒ4@ (** *ߟLhxx84P(lhhx)B t0puuEzj\%aZvvvvvvPPB2""wEޞýdÜc\r!m``. r!t4N:XVVo߾}IRБ#GOixj th$Jwݷo߱cǚݼy3<<<<<޽{iiicƌ۷ݻO5-ׯ_>wܞ={'%%X+gذaIII/^ٳܹsׯ____f 5P6&&G\.7""͛y͛7#""\n=bbbjkkSرw@E:VVV|>?***??-EEE|+++X\YYIGZ 55!s܅U@PL$DǏǏE"H$*//Nz*B* tR\\,bӧOjӧbX$Sղhllr]P>>wdKc@ ]2VbTeOO9s8;;edd5 w]m5jԥKҜ̙e]`i0wYD" B BCC_~zhh(AB066V"ஈFuuuA=zw! t Z,x[nuGm۶mƌU i]t-rX,iQ;ҼܹC߁lmmׯ_O_&: S"H S$//Юv%ə3gW|hΝ666WB/ƕwUUUEGG#|||;СC>9aH$ߦjW_uiD"###rWYY vh͚5r\Pz !dmmM߱O>uT4)**׷Ϟ=eBԢgϞb rOQQ%ͶI٥z;g}6p@4ѭɉݻwcT?lذ.!jFUWWXZZ oi̙\v?leeE!t%t9}ӧO˔WHNrppp8׮] b䛊hhh W^>ΥK pwwB˫<<55!'P۸ҝ;wB> tə0aA={_>tjjjrrr֯_okkkaaNCSWWyfr\ĉ)_7c!jUA?~M9t>3CfHՍ/R~OmΟ?occJ6׽{͛7>6OoA``2+!t}P( $ jANӧ6`i"mrV+W¼4bVdvv6ݔ#w LKK# |.˗B-`,Ŝ4򎲋Kll,x$Irrr~~~mܹs RӧO<(ؿ?*XqZZ+ WW)S<|077XA,_חt(tH7n &9;;S8+4 |)SΟ?OIaXgggr7l onҥFFFܴiL&@.MvlsCsNDDdz/_]]^|)ɹZѣA.t@$EGGWTTஈJfff"wEԻqB6,::'ODGGDD95::ɓ'+˗/BO]<\,w֍a*77wE%w֭X,օwͷlق :oxyoy}uֽ{ȹvvv3#W]mSSe˖gϞӧτ pr}={~]l)BhfPK IDAT6/[,??Ν>D(Yݵ֬Y# k%$$丸 2d˖-B8;;COG(%i\S媵S^^.LMM [OJbDDDh]2vعst>}*̌:X$O7-,,|||=zDE?1b*@gAPehhHΥxa^x!>|د_ݻ:u5ط~₻ Y:8qA+W#Gܻwݽ{744WMM {,۷oϗJ CcǾ{ >..ɉʕ+/dff999ũvj\\u:ud@!ݿ G*"H6l@Fϔ)SLp7lؠഴ4;;;77[nٔ*--Eѱ3,Ya{ݻ)kӧ#F044ܹs'Umj\n``g܅NQ]LLL֮]p1MMM(ZNf'ww wS`p v܉?>x111{GY^^px\s C%\iӦH ,̘1#+++55K X@h*?~ѣG˖-(ěZ^zeff~}lA tnܸq /&$$|WW9sfmm-P($.t BkZmo۷E"B4:hР㮈^ӧ С͛===Ǎyw}}}> B:Ԩܽ{EضçMrJL"Z888| tc7o<܅A__?..n׮]6l=zgpWD=.=:mKLiӦ9syYǏ4ʕ+ˡ<5:HJJ*..^t)B:s޽{nݺw9 46l0fwww܅t{'OFFFᮈ2:uٳgQ"'&&;vlذaZ;:ڴiS^>܅t\"J tiP@(~w!:jسgϒ%K3233'N8nܸ5kr6:jٶmޜ9sp";vl޼o d\5 tT'J7op&.?=͛7oԨQ ^HHHfffEEŠA]4, tTӽ{~G ˗4hA@PUUU]]Ul۶$22w!4255=xڵk͚5K#$AtYSSw-"bٲe)))gΜ]QA:,eӧOIygeee 0ȑ#i a9.۸qĉɞptt %NlܸqРAÇ]{EEE߼yԜ t:VZZ;T6hР,r*z:,ӱ8KK3f.DXYYZ~B t:P__믿.X@__w-=zFz z : BZhB4ĉ\B.?x%&- Eqq1Bxeiiу޷o9vSN]  drKy)X = &333AGedd.JX>O.?A̶ṉ@WAO r!P(*++wMW_}'UeAf:on.MMM ӣG4hPbb"4Z``rG}86yCeeeJRЍ72 .,Zhʔ)t/?` AIIIDf~ƍ'LK`:\.f4k֬ Z3.yCee%τ$$$t~wUUU 0`…/d2YiizeZ@輡kX͛CBBԣ5k,X@B1c͛7lr)':wm濺m;vС/"99Y.s89s樼Ja'] +W̟??>>5˗/ϧ83^n;vlFFF]]kL/_\zjm\XXι`ȼgώ5 !dooOP(ܼys]]̙rB\.722R.cV\vM__A TkpРANNNkNT*߿?B/99YPD"ݻ⊊ BnCCuׯ===[MxoCn nfaaH$222211D!___D`s\ru\V@Ǵ6t$Ill@ "44gbAfffٌ >vZP\GEEQ@0tb Nj}v'_X]]b KKK>Ckt??? Z_aYm_S\t5*t***bq D"ѣGThױ'888++:AkcǎWp87onp5NiiH$211122Dj6NDppK(tqqqAx<q##bkͧSTToaa!={Fa㍍B( 11Arss>}WX>εй~DDϷ}MdlODä{-Y\ѱGp5FNVVVpp0qpp}53MKK{BJW5?}k-as%rH{||<{iiiBFkpƄNbbb@@Bw9xL&[ύ7"""8@ s:r>>>'&&b6w툈gcc#pW\9_~#G<="EGGԞsS:... 6{IttrjOii)4kĮ!'8;;s܈7nந˞?"E}}=NYl /_bkkkr͝;wBAAAHHۺu:?dCCCwwsfffv ҫWbccmmmɩ=W6G 84&Ċh333rMAA <ֶ)66H$gΜ!_˺;wp8]zHGGGrjիWUn/^ %k\ӧB%%%I4O},,,._LGiii#GDDa&Mj~㣏>bx"h= Ça:IOO'=<<D_®~Q+wޥH9 X*dEEE۷o'ׅ@mܸ;mh: "44t޽zpD{g&u֭ 333SByjjjrrr֯_okkkaaNCoHKK;v,yC–'Nzw(lm\ws}U')Cf{ B.zW\INTH$:tPUUH$IR [=B(??f纫(9+WoZv [^^^TTdz􍎍0arŋm?ZU9fС4k@ 6n}k1W\AAH$244455DԶuVwwwrL&ۺuw_T#z.L.tO8JNNFZCZs!1]ӧObH$Fzz^kΝ;G@*>}>J理Bbcc{IoygXXXAAjkk8P\3pi9S[nzzzo-#8NO_PPPm5SL9)уxMZnmʕzzzz/n sNjjjbcc8Nhh(,qVVV|>?***//wEJs>..ɉ)d_*//D"Us l됧'B( %%wEj)..Dbӧ+b8:-C" 8w:r~X,ң\Zg+tHr<11!)ݽ{744HAl %C}cU233i5NNNqqq+oee%++++DN!kOMs[aC ȩ=eee | -B06T<~4.ϵƥ)4,td2ٚ5k\nhhh^^X,677'TCP($"44r|̘1\.Rƅ\t ]ISRR2|p##xcbb,--ɩ=ž<׀*4GGG@¿cԞANLQNݻ:q8ղ ;׀ _~?BBo=ڵkM*Oټys;|>ۻTAW1pX: B"̘1P5K95..{777wh &#055򲳳!k\? @n\} 2___ 'NPٳgɭlll >7odϭ#wSSSrb1 g\ۓ䧟~]`Ydgg BWW۷ow==QFڵA4IIIApܐ􂃃 Eff%Ks=t˗)tN8ajj:rH5o⴯ !t!:_jՐ!C?YYY={tssx͚5kĉ4yk֬?~9sOKKK$HBt47dffZYY5322 q\nnnyyyHҨ/~ڸqM122(-ڦ,X 44R;ѣGL} Ѵ̨3gNbbݻg͚ di鴃C {nח9::EzjرɧOf&q!M>̙3/^/**RrssCvBѣG.] dX.p8~~~W^U155]:Çd/^$'0oOx…ݻc%ڭ:a۷o>G  211?"###""6oތ؀w=z۱c,,,>:BH"p\Ϗ[xqEE"ziU:FC#Gӧϱcp5jkk Mk֬qqq?~~~mY.؀+W>rGlqIO~mBddyxxxUU \-Nzo ۫Wȉr=+WÇg,qPJ$BhҤI'O<{qjjjpZߺ"xj=nܸ߿yZv{wSSSܹ{=w9=trrrF흘Ȇ,R8p`JJJiiiHHׯq8NϞ=#G;))%oyyԿ3g?|=h O=֖=X|y;拉=﨣͉ ;B&88:ǔ͗WJgϞ}رc:Zpy-^\\Ķg,RHMMχܡϫqh ?0--ɓt_^)?ətݻw:tLJէWJ?vؕ+WfϞ OQB(x<(?OmTH$! :رc'NOqע |3iW\7oއ~((lZ! >;v̚5k<#{:/^ܰaƍY8mJiƌs΍zZ4l SSS1eʔHj v\^)ϮMMMk00#C>H$ Mk.HѸk0X:g\\ƍY>*ZlzEGG-[;v w-M*vXt9tϟ?m4xFނD"aT:uY.\˹wl QCocЉW矹\.ٲUXc?ӆ lmmi*Z bŊ]ׯ_ojj_9Nn|IZlϦv5jԨSN6 w9TTTobbsNrhУXExۼϞ=v˥& ZXXr \P(R)B(11q„ Xk󓒒޽˶%bYq999Hnp5_Sօ˫ǏlڴIS!dllCUhhرc,X@v@ |=S#H>ɉ(ЧO?7nmyyy7n+Vh\ccA::D"Yr%dԩzzz,XA7:mҥk֬] -_w:8t tޝ0q?dqCիW#bbbpF+Wl `w%mllo׺uqF_T~8NHHtH=Tw͙3G& K*j-/^_.);;pig޽{y<ޣG@8qB!am˖-qPWWףGxSNHtYnԩS{Ic1#z-XPb޼y={;;m200ЁȌj'222BE &L@Akaȯ_ZZ6'oE_|||?M2EP{**sε]7!̴QMMц hͼ^z^VVt¢w!׿L?[om>|\?˗3OM]]3x8coҥ}opBܵtك|}}.b֭]6o {͇3744, 3fl޼YC!}%=/^3\ ŋoݺz[$%%qܐt)%:#FuӢE>} 3_ -,,v؁ ̚\kFgϝ;_ms=3F;wY >.\XRR|X:.\иA\\\ƌv-CG.gff>K5V-:uTnn.BNk:>|,/Ǝk.܅2t_ׯ_?,Zqܹsڵ n'Zݻw=<\SSZNAA R3e2١Cpt#HpUDh"kkkKKŋ744t999~5W( &M 9~t-88Xwh#Gu}̙%%%+<{ !|( HMM%bȑ/_ܻwo'_)pe˖6wIɓ'¸su>!aÆfgg.x!dmm.pBRRҒ%K߯_K۷ڵk|y}}=Q8 秦8qYYYi߽Q~bo?YPPn:uyBS1]FޘxoGڿ?ΚP(Mի{S&W(4ZZ !G?(8=:Ul?!J~K~|J@@@gt$''ԔUwʕe˖9::R3rssoݺEa,'$###$$VOO{l[o.B!:Nyy9B[nd픔dddxyy}7l{C^ۛv}}}>~Sl'D$]p!33իW۶m;p@TTMOoNSSBc*^|200 %㲲R iiiiii|rЦMhUU Dr…ׯ744޽[f 4iSUYY) &M:wwUg}×/_O!j;Ŕ`[a#?LRV" Iq\/B޽{T6ʕ+-,,z"~[4iҭ[=z~SE'jӦMB}O={_QQ1`3grP`` ڣ١RB Z# SE QΆ#?O>T堠 KKK J~CzzΝ;i*RM~iiiׯO?~x5?!VZv}y{{T$Uۗ2z蠠 ܵGC'""!J~={j]z!4}tBǎ#>Bh̘14>iҤ'OP ٶmB?D566R"EN<9o w}ɓ'4K+ ~SL<7Ay :tڴi}{l=pW H{:Ak˖-FFF(GaU}ut&LPWWיLPBG0hĈlh @#Fq9pAP(`@+,  !4bĈlr!hBhذa/.h?Bݺultq* ~?>uԼyvE"B\/;;w!B"ܹ׭[wersbmm CAS]]}ĉUV-\pEEE+oo7oB'888,]\D.*w9w\P}!tx{{CO1k׮ms&rti̡O.eB&&&xlUп\@dR/!!ؘ'&&у|3ɵI1+,,l~~~ X?+nnn2X7^_ĉ97&+FLJJd /abbafagpLQ$tɒ@{۶mV9-|VVV X[ٳ?#|7|?;kggBUX___ 7l_-Z: By|>fff^=**ի ܲe ) WX8::>| +W?ݻ˗?EM2ŋxxt0 { ?׏9|pZZڀ` xwqM]Ož*ą nQjZV՟uઢb*ֽ D@PCe>O BHn%7~3p9۷dW :.zѐ!C<<<|pSN]N7 t? "['&BHKK'AHOH!Xv@>>wss=rH aڵׯ_"CSlmmLgqQ\pB ,,,%%@ tWQQ葩SZ[[Bb#QrJt ߄SԄ֕ëg"Ə8n8P\\ bs!p3k֬KSSSM&fIII}!oW_}%Zs,ͱ0f777,++CIT|m;FݸqIGGGfǏ/m#HAu&cٲe?2:!===GfeݺuFFFx "!ϟ5k0L1qD\JNgʔ)Ǐ2:>}Bb?bKTWW󞐑`0mBXTT$G,^^^b4i$\N 7A e111="&á, /{X!˥hIMM4h$''[ZZJKPGGx ]Y`A]]ŋ{ NB>m۷8ڵk{űBܝ?~̙ⷓ$VH!&t`ԩ! 6˗/>}3fMihh?~BөD\ŋ?SUUCEzt 7+ .LNN.--~ Э[(D_ߟdU$rssutt,--l'--B}?OEzt 7SӧO/bbbzNۛvd@.ݷoϟpMMM\.~YfyF䪸ȳvڟ~Iv.\,~;&:z~s`cccRRRhnwo.֬Ycjjf|lNCC7|ӷo˗׷}ã-OMMݺ"rU\ɄUnnoӦMC19{ؙ&ࢨB$'' [md.tԾ'O .D(.@:{]...s:@7oիم|…Za XǏ| .dd2ҦLBv!@7ܹs<BGܹsdN:B={͛7kjj}&ILS{ IDATL166& f͚f\3!t͛7 HH>}Ǝ+(++{1ٳg_~kX:"11QUUU{?͞=b]vM tEbbمBp8III'O& f͚u zA(NI򪯯hdddkkKv!@ΙXZZ BG!ܼysr<'NLNNW[[ V&Lw!t_jj*Ñ0aB(55'@ȿ7o9wd#ցБpl$t*%%HBIIIqqޡŋ#G]^x ,&Lm۶W^v|бBHKKΎ*Bիd" P _`` %HjzzzC9>>Ϗ8m׮]6mz6ٵ(..B/B(>>B䄫Ç;>tBh,K~3+**222ğ=z46VG:!Իwooo?Bpvee対BqppxQCCCLJ t+444???//BtI&ijj]P8l6;??C:>dȐ( MmmmJJ [RXXX=|C:ZdӧG%&&Xӧ]PPvvv=B_rم̙3d]AAA:՝3gNdNyy /^Lv!@q 2oi'44K}2ɓdmmmmyy9rv\\\ &맓\cTUUɮ(. C[xq\\ܧO.DtϞ=[d مf``QRR·B߼yTLN1bСC.(4 2p@uuugϞ]`م PZZʷBd"Gl dqYYBN=zĈx:e݋/իٵ !t `pi_YYwߑ]!ddd;: 鱱d\.t$g``P__v!N455Ν{ak֬!KOO!TSSv!N-[VTTt ֮]GEv!N~ɍ7VZEv! BBCCϞ=[UUEv!۰aȑ#a UB|@ﯦ&.\a PSSSۅ:9rDO'oٲӓBhGYY!v!N7BCC矴4 Rnnŋ7nHv!hT*Bn :YO'o޼|҉NCXhh{ ă\~z s,F]=___MM͘ իlZfcgvx t6o޼(Cv-;w.55u߾} Zv`E.ҥK_xqm Wss?8w\GGGksu+͘1ct+**~7 K!mm !tz…CۓǏ7o 366&u:C@GWWWJN'o޼YUU.Z)##G~:ׯ: Ё+хz*992.]joo|rr[:h{:wΜ9sRiWVVfhhwKYȨРo>}СC/_L&ԬZjɒ%0R׭[Phh(m455IO.-gggUUU;;ϟ?ST˦&b&_lmؖ{فCv…Ç'@yi.PX,VBBرc̚>QnF}m߾wiĈ `٭@իW&&&| !t뛑rY,ߣY|aN͛7} N "S\\laaBG(ÇWRR7Iy޽X8@Q00E?}dnnηB9tдi:KJJ6lO?YYYItCƆo!B2d5)%ɓ鈈J 6ܑ]dڵk%5|%vSh4Zpp0Yȓϟ+++9ѩ]vظcH4tbbbܹpf.ad#Omll:@@>}455ێFR%:>|Xf͊+ &M(8ѣGΔQTGG[|(((:th:=cnn~M:λɒFI.t.\e BOB^ :.1xTr{:QQQ׮];y򤺺$?|𡬬ֶC:#}}l6=={8qHڜ9st:N={6ٵȉѣGw]\x1"czzz&M¥ALAAA5|p92#f[dooob6rӧ-q{O>Ji;Kw||-&5JB.ۣe޼ys]9|}}.g؋'Iy#ĉmfdd0n.8::u55)TjTTANNN~~~kk+I|R 77[!DFF}!dllZlB())H%Ν;Ӛ:=vر۷oR(-xDX<<>BHjjqRSS6C4pNйyҤI&R+0._u tl}||F{㰧wB =@;o߾W^mcc#!t\R__?""BB_/^oܸ!Dz€=~~~SLV t^SSsNn!;wX=*--o-Z-mAlvPP޽{ ^mۖ%VB=Zvv͛7n8bb*//'l:(iӦ;wNI3-pNիwjii]O:u9+++7 W(ׯ^:""b֬YoB`0fϞ|r# Bk.j@QN6166J%wB3f+..NYYJ򯦦fʔ)YYYzzzĉkkk322$=l0 tgXԤ]B:ȱZOO߾}[JdUuu)SJKKoݺ5h r!//A o=z_]?JffСCH:)Dž Lzybrb׮]gϞ1cƹs.KpԴ`ݻw\r˗/9B7Jnni j̙>LHH `*AEѪ\n6449lȞ?>k֬ʛ7o]PPP&&&cƌt*ڿ+W=ZYY9''GVAE$CҀb\rƌYYY2qO{:4mΜ9#ooCEFFFEE]Q@ť7ydv!F|TVVv) EGt:?dWlC\]])q!??V???kAEEEnnn+W OOO "AƎ?vXhiiYvy dWOAECh4󟖖R5jԁ<9x`R P\L&sK,qqqqqqYdL&ae455mڴՕNgff88m9so rÇڪaaa/_Ė|2,,LUUU[[;<<Ǐի{immP,o߾ TWWpuuuMMͰoJS԰0Mz@E eee==*ϯSVV z9^0p:>jԨ\:@=}4((NFFF nmmmdd!N z\zuڑ r<BȳӧSTcczک466RӧOm, !+*:@>eddL8!4hРflnn8qbff+//_ͥKƌ1bĥKl6x>1c\tIoޫW/CCØ܋E:@N옘aÆ!/]p$9s%GGGаa6pbbbLLLo.25&&!4}tA vgkkNMMuppPRR 22dFFFQ(ӧ߹sJ )#B0a;}t\m Wcc;V^˗/crHzʪ'\*ھxӧOJJJ!!!dWį8$$DIII__?""ӧOdW$] t(// RSSkaJ:aݸԴɮHZ@͛0 J+VeeeDDq ՞={uիWDDćȮH|ݸ={FvEdRɓ'شX:yűc _O555KK dggPER}||Sލ/_Μ9SGGb BHlTDnޞ7k566`k}d~?۷/J믿D655EEEƕ#Nk=ջQUUe``6d###%W"eo++\itVbb"BhРA◄]S3fLrrm ڰa˱-,,$X@ t).X܌9Sx6^K.1Dk0_-ǏB+ndb'N>|3\OOO 3f[V)..F8d:Jrvƌ#F8qk?MF@rX'Nϟ? #++S:'ꮯOJJ;wmBxzzfee1 cc۟8q7ٱ5Fa-B(88XkWX)SSSTFF.Zm 4ɓ' idd$ķ}ƍMMM%'BD7==-:\.h޽$MKK۷/B(<<ߖڒ7 VTTF:tH+B3txܹ9r$~ud؞3|hjj5j֭[\'ܹs!S @IIIXXJ>}"""%-B!_iTWWGDDGEE%,,D[ .q8nׯ_GHhc)--m+L[+t222B666_eeeٸJKKqOѣG---?rlѣG &`߿UQQ y5^-766&%%ukZL&355[˗,2>>~ %..\ׯCBBTTTtuu#""޿c|z7222Κ*ݶsssB/^YTT$~.:;;uJAIDAT{xxN722NKK*LQQ6W޽oNFW_J\vPAA6@^ú&ݻww=sY~D*څϟBׯ_'0 SؽQ2dF 8'_7. |yPP1O`B֭[NNN!Ǐ X622NURaa!a 22G'{ ݂x]r7n\VV׷ƕ'N1X)ccH)::`kk?\ |BXg#G&%%֍!4qD3'33}a``%1a]LL –!&L`0$T"UV }777nPb2tnn iMMM۷on#O:pԩƥ(ܮ0aĺ.[VTTZjd;d PX`ɓ' (.0te˖M2ٳg% 2݄Nccٳg ('''??!C|JvQLݏ_xj<)++ q8u-[TUU\~ӧE%ll;;aÆ:uJ5YrϞ=q '( =GѶlLBBvc1${:iӦh4\ZZ333}||6l؀ zvsO<9zR&M;v,NȈ=ճб^tMjjj$TNϟ?5jTuuuRRRjj E"""8κu$Q B^ 2dH~~3gx N޽|...f!. GD]yϞ=JJJwf Z[[?|@vE@>xxӧO󵴴B@$lm۶-]t͚5d P(Ǐ7668Xlٲɓ'?{%'}ݻwѣG]WA0ovvv/^Ɂ)v߾}{BB. UTTܻw/..pc1 ^ -Zɓ'&&&x5 ۷8p@[[{pc1ߧͅˮ䪫۵k9ڵkWXAvQ o \\\ L@]v555}aaaz"(s ^|8v3g"a7_eeUV^OvQ333s]xqǎ7:r-[6ugϞm߾H'Loׯ_Dd'''???[[[ltKuʕ_9s222$ `0\]]'M}x H? N/}᯾/˓VÇ'MNR FRRѣ. H0th4ɓ']\\BG$i9V\\;r>$%%]= A)++߃ >> i*B֭Qmɟ>}MC9sFszc͛6m搨EE$DztDMa|رfZr]=%iW>aaa؁^uuʁȮU<|L0̙3dW$Azzz!~Ǐ]BЉ FX!O:,`xl0l3g͛0`@nnnNN-33֭[FFF?=Q>'))iFFF!*l2;;***ƍ۽{7Bĉd@gؤ$]vU1&O.c dcO[IIIuuumw#G]tА!C.I8qbڴimblv-XNRIݻwB| م= &`00LPSSSfffۅ=ںuߍ9o޼YlYUUB1%%{=f9''gΜ9CmzKKKVVT1-,,fϞիW,\1nCɝqcW/ϟ?>566v[0w$wUƷ~>rlDIdй#| bNطo߾}.I@.A P:BA P:BA P:BA P:B9r/a@[EBBBhh(YHU (R20@A9 t B@>82̟IENDB`tins-1.32.1/examples/prefix-equals-suffix-reversed-with-infix.stm0000644000004100000410000000216314353307475025153 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with a binary number on the tape: # $ turing.rb prefix-equals-suffix-reversed-with-infix.stm 100101001 0. right goto: 1 1. cond if: '0', then: 2, else: 13 2. write symbol: 'O', goto: 3 3. right goto: 4 4. cond if: 'B', then: 21, else: 5 5. right goto: 6 6. cond if: 'B', then: 7, else: 5 7. left goto: 8 8. cond if: '0', then: 9, else: 21 9. write symbol: 'B', goto: 10 10. left goto: 11 11. cond if: '0', then: 10, else: 12 12. cond if: '1', then: 10, else: 0 13. cond if: '1', then: 14, else: 31 14. write symbol: 'I', goto: 15 15. right goto: 16 16. cond if: 'B', then: 21, else: 17 17. right goto: 18 18. cond if: 'B', then: 19, else: 17 19. left goto: 20 20. cond if: '1', then: 9, else: 21 21. write symbol: 'B', goto: 22 22. left goto: 23 23. cond if: '0', then: 21, else: 24 24. cond if: '1', then: 21, else: 25 25. write symbol: 'B', goto: 26 26. left goto: 27 27. cond if: 'O', then: 29, else: 28 28. cond if: 'I', then: 30, else: 32 29. write symbol: '0', goto: 26 30. write symbol: '1', goto: 26 31. halt 32. right goto: 33 33. cond if: 'B', then: 31, else: 32 tins-1.32.1/examples/prefix-equals-suffix-reversed-with-infix.png0000644000004100000410000011167414353307475025144 0ustar www-datawww-dataPNG  IHDR|4*bKGD IDATxw\3[MJ56JQQ * +ƨk&A7YM#1Xbcl[ (D myܽHٝ3|{YgyfBP ` w`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA .\x5U< t[l]B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B(B.]k.)))ѣm~,Y28UVK&9::2_.Mjj ˝5ksRPPuV~=H8:B0dRy<ޜ9sp+//۷o7₱*0DFFr\A 0G@̘1C.+p8X`322p8666`TDD A:Q!P(t `TnFI ]B0mΜ9 bݺu] @7} H&<~x `۶m;xzBB(p0܅@O˵/'AKo{:FA`Q:FA`Q:FA`Q:FA(SPP}3guUěCBBN>M_Pm%@ɓ'{I_U[[̗}=x>ضm=E `@ (Ya\4rСC{#c@&@zB t/++C 06:uWZeooqFܵA&uk,}}CY@@Q(K,A.BKLLˉ'֯_@ .;v "::֭[ԃxↆ3f.P BP.%%jhhx"3g/ݻ7k֬ VM;otl+ (cddݷmk``zԨQ&M:z(y5bĈ#G9rUC:2ꫂr9eQ "FMpy`Q:FA`Q:FA`Q:FA`Q:FA`端ںuk_P455|jsss_4k/ʕ+=zԥܽ{cƌr*̙3*׭[׭[7B(!!a{9sj-[nŊpJ_W{y.]r 233 xc( t@UWW2.%%Sݓ'O\;w޶G 2]##""$ɁI'O d2蚯Ӈѣ:V?N]p5klذaСj6ɯe2۷?v@=YyyyC 6mږ-[o- \.o߾7n܀;;ZBtJmm lM*444'Ǝf t/^=zTAݹsux/BA耎[ vvv4xORiVVVrr2%:p>,&&& 6/_y<ի: `'SPP0x]vQج[~~oVV)<`VuuuA\xАfuP(|>AMMM䇐yxx$%%Qx86x geeQzzz...'Oζiz:m%KN<9zhZt)SH$ZXamHKKDN@ P(th,,,lҤI?8P(D2p,: ӦMܹs'33ufnncn$7|'411a:vܹiӦ#Gxzz2y\@; %++룏>ZjդI>P(+BŋSN1bė_~ѡS td|>2ccc# ttWUUɓ vZܵ '''%###ܾ*Bz:: `An_uyܵ @ ]`tt}ƍ߾*0TGw@蜼ٳgϟ?kPX\\,qh[jkkLҧOw-oeee ! "22ŋ -}YWXBG[رcj* Cxz+N>vZܵP=-$J}~A~AA̙3#"">c`hϧ]|ygʔ)Bp͸Kk:Z~xR4))O>/))|* /BGH$#GHRPSSSIIIII'|B>b3@PTTP(Ytd2LwEGGd2uH ={ w!^:fmvWWW3_R'X:BG;v\.?+$O͵V?nN Yf}gY<z:Zn$kݻw r{}aÆa`.xYjjjk+>;w?ql=Am6wwwUu@ ~:*=C{x;w}ւUl̬[np[Gk)@' 8k?nkk<66UKEEEmmszںuj4jAٚU() thaCCׯ5 !iӦNhזFFFAAAoUl 6b:;r}||lmmcccB4z5Qڷ O͵v9n8k777B F t6BGAnРA\.!rkV߸q#5Qڷ) ) v- .\iii|?tМ"|]"r9 J:Ϗݳg /W(K,AR]e|$r| \ai%444\2 @Fbbb\\\N8~z k%o!diiijj CD"ʕ+B BFwADtt[MKV:Lضmٳg7 rɑ,* ZxqCCÌ3ꨭSMM thx\ \ f͚6_pE3g466^dݻwo֬Ys"6mv,奭 th7uT2,8Ό3 6_k``3jԨ0"ȑ#NNNTey]Kyi+˜vxRedPP\.W,9̺5@PZZ*Jyyw!J:`,^OOnh^z:ZB >:੹} tWo[Wh"j@"<w!2:?}tB LLLpV>dҽ/RYYzjZ҂rrvrppr?@TZZ: >Ro,a9\.KIGKA0- e2X,Rf!h:y{{7 ~qY`a8p`@7K`)/MᆱG~p<=='M$ 5Ea Nޒ4@ (** *ߟLhxx84P(lhhx)B t0puuEzj\%aZvvvvvvPPB2""wEޞýdÜc\r!m``. r!t4N:XVVo߾}IRБ#GOixj th$Jwݷo߱cǚݼy3<<<<<޽{iiicƌ۷ݻO5-ׯ_>wܞ={'%%X+gذaIII/^ٳܹsׯ____f 5P6&&G\.7""͛y͛7#""\n=bbbjkkSرw@E:VVV|>?***??-EEE|+++X\YYIGZ 55!s܅U@PL$DǏǏE"H$*//Nz*B* tR\\,bӧOjӧbX$Sղhllr]P>>wdKc@ ]2VbTeOO9s8;;edd5 w]m5jԥKҜ̙e]`i0wYD" B BCC_~zhh(AB066V"ஈFuuuA=zw! t Z,x[nuGm۶mƌU i]t-rX,iQ;ҼܹC߁lmmׯ_O_&: S"H S$//Юv%ə3gW|hΝ666WB/ƕwUUUEGG#|||;СC>9aH$ߦjW_uiD"###rWYY vh͚5r\Pz !dmmM߱O>uT4)**׷Ϟ=eBԢgϞb rOQQ%ͶI٥z;g}6p@4ѭɉݻwcT?lذ.!jFUWWXZZ oi̙\v?leeE!t%t9}ӧO˔WHNrppp8׮] b䛊hhh W^>ΥK pwwB˫<<55!'P۸ҝ;wB> tə0aA={_>tjjjrrr֯_okkkaaNCSWWyfr\ĉ)_7c!jUA?~M9t>3CfHՍ/R~OmΟ?occJ6׽{͛7>6OoA``2+!t}P( $ jANӧ6`i"mrV+W¼4bVdvv6ݔ#w LKK# |.˗B-`,Ŝ4򎲋Kll,x$Irrr~~~mܹs RӧO<(ؿ?*XqZZ+ WW)S<|077XA,_חt(tH7n &9;;S8+4 |)SΟ?OIaXgggr7l onҥFFFܴiL&@.MvlsCsNDDdz/_]]^|)ɹZѣA.t@$EGGWTTஈJfff"wEԻqB6,::'ODGGDD95::ɓ'+˗/BO]<\,w֍a*77wE%w֭X,օwͷlق :oxyoy}uֽ{ȹvvv3#W]mSSe˖gϞӧτ pr}={~]l)BhfPK IDAT6/[,??Ν>D(Yݵ֬Y# k%$$丸 2d˖-B8;;COG(%i\S媵S^^.LMM [OJbDDDh]2vعst>}*̌:X$O7-,,|||=zDE?1b*@gAPehhHΥxa^x!>|د_ݻ:u5ط~₻ Y:8qA+W#Gܻwݽ{744WMM {,۷oϗJ CcǾ{ >..ɉʕ+/dff999ũvj\\u:ud@!ݿ G*"H6l@Fϔ)SLp7lؠഴ4;;;77[nٔ*--Eѱ3,Ya{ݻ)kӧ#F044ܹs'Umj\n``g܅NQ]LLL֮]p1MMM(ZNf'ww wS`p v܉?>x111{GY^^px\s C%\iӦH ,̘1#+++55K X@h*?~ѣG˖-(ěZ^zeff~}lA tnܸq /&$$|WW9sfmm-P($.t BkZmo۷E"B4:hР㮈^ӧ С͛===Ǎyw}}}> B:Ԩܽ{EضçMrJL"Z888| tc7o<܅A__?..n׮]6l=zgpWD=.=:mKLiӦ9syYǏ4ʕ+ˡ<5:HJJ*..^t)B:s޽{nݺw9 46l0fwww܅t{'OFFFᮈ2:uٳgQ"'&&;vlذaZ;:ڴiS^>܅t\"J tiP@(~w!:jسgϒ%K3233'N8nܸ5kr6:jٶmޜ9sp";vl޼o d\5 tT'J7op&.?=͛7oԨQ ^HHHfffEEŠA]4, tTӽ{~G ˗4hA@PUUU]]Ul۶$22w!4255=xڵk͚5K#$AtYSSw-"bٲe)))gΜ]QA:,eӧOIygeee 0ȑ#i a9.۸qĉɞptt %NlܸqРAÇ]{EEE߼yԜ t:VZZ;T6hР,r*z:,ӱ8KK3f.DXYYZ~B t:P__믿.X@__w-=zFz z : BZhB4ĉ\B.?x%&- Eqq1Bxeiiу޷o9vSN]  drKy)X = &333AGedd.JX>O.?A̶ṉ@WAO r!P(*++wMW_}'UeAf:on.MMM ӣG4hPbb"4Z``rG}86yCeeeJRЍ72 .,Zhʔ)t/?` AIIIDf~ƍ'LK`:\.f4k֬ Z3.yCee%τ$$$t~wUUU 0`…/d2YiizeZ@輡kX͛CBBԣ5k,X@B1c͛7lr)':wm濺m;vС/"99Y.s89s樼Ja'] +W̟??>>5˗/ϧ83^n;vlFFF]]kL/_\zjm\XXι`ȼgώ5 !dooOP(ܼys]]̙rB\.722R.cV\vM__A TkpРANNNkNT*߿?B/99YPD"ݻ⊊ BnCCuׯ===[MxoCn nfaaH$222211D!___D`s\ru\V@Ǵ6t$Ill@ "44gbAfffٌ >vZP\GEEQ@0tb Nj}v'_X]]b KKK>Ckt??? Z_aYm_S\t5*t***bq D"ѣGThױ'888++:AkcǎWp87onp5NiiH$211122Dj6NDppK(tqqqAx<q##bkͧSTToaa!={Fa㍍B( 11Arss>}WX>εй~DDϷ}MdlODä{-Y\ѱGp5FNVVVpp0qpp}53MKK{BJW5?}k-as%rH{||<{iiiBFkpƄNbbb@@Bw9xL&[ύ7"""8@ s:r>>>'&&b6w툈gcc#pW\9_~#G<="EGGԞsS:... 6{IttrjOii)4kĮ!'8;;s܈7nந˞?"E}}=NYl /_bkkkr͝;wBAAAHHۺu:?dCCCwwsfffv ҫWbccmmmɩ=W6G 84&Ċh333rMAA <ֶ)66H$gΜ!_˺;wp8]zHGGGrjիWUn/^ %k\ӧB%%%I4O},,,._LGiii#GDDa&Mj~㣏>bx"h= Ça:IOO'=<<D_®~Q+wޥH9 X*dEEE۷o'ׅ@mܸ;mh: "44t޽zpD{g&u֭ 333SByjjjrrr֯_okkkaaNCoHKK;v,yC–'Nzw(lm\ws}U')Cf{ B.zW\INTH$:tPUUH$IR [=B(??f纫(9+WoZv [^^^TTdz􍎍0arŋm?ZU9fС4k@ 6n}k1W\AAH$244455DԶuVwwwrL&ۺuw_T#z.L.tO8JNNFZCZs!1]ӧObH$Fzz^kΝ;G@*>}>J理Bbcc{IoygXXXAAjkk8P\3pi9S[nzzzo-#8NO_PPPm5SL9)уxMZnmʕzzzz/n sNjjjbcc8Nhh(,qVVV|>?***//wEJs>..ɉ)d_*//D"Us l됧'B( %%wEj)..Dbӧ+b8:-C" 8w:r~X,ң\Zg+tHr<11!)ݽ{744HAl %C}cU233i5NNNqqq+oee%++++DN!kOMs[aC ȩ=eee | -B06T<~4.ϵƥ)4,td2ٚ5k\nhhh^^X,677'TCP($"44r|̘1\.Rƅ\t ]ISRR2|p##xcbb,--ɩ=ž<׀*4GGG@¿cԞANLQNݻ:q8ղ ;׀ _~?BBo=ڵkM*Oټys;|>ۻTAW1pX: B"̘1P5K95..{777wh &#055򲳳!k\? @n\} 2___ 'NPٳgɭlll >7odϭ#wSSSrb1 g\ۓ䧟~]`Ydgg BWW۷ow==QFڵA4IIIApܐ􂃃 Eff%Ks=t˗)tN8ajj:rH5o⴯ !t!:_jՐ!C?YYY={tssx͚5kĉ4yk֬?~9sOKKK$HBt47dffZYY5322 q\nnnyyyHҨ/~ڸqM122(-ڦ,X 44R;ѣGL} Ѵ̨3gNbbݻg͚ di鴃C {nח9::EzjرɧOf&q!M>̙3/^/**RrssCvBѣG.] dX.p8~~~W^U155]:Çd/^$'0oOx…ݻc%ڭ:a۷o>G  211?"###""6oތ؀w=z۱c,,,>:BH"p\Ϗ[xqEE"ziU:FC#Gӧϱcp5jkk Mk֬qqq?~~~mY.؀+W>rGlqIO~mBddyxxxUU \-Nzo ۫Wȉr=+WÇg,qPJ$BhҤI'O<{qjjjpZߺ"xj=nܸ߿yZv{wSSSܹ{=w9=trrrF흘Ȇ,R8p`JJJiiiHHׯq8NϞ=#G;))%oyyԿ3g?|=h O=֖=X|y;拉=﨣͉ ;B&88:ǔ͗WJgϞ}رc:Zpy-^\\Ķg,RHMMχܡϫqh ?0--ɓt_^)?ətݻw:tLJէWJ?vؕ+WfϞ OQB(x<(?OmTH$! :رc'NOqע |3iW\7oއ~((lZ! >;v̚5k<#{:/^ܰaƍY8mJiƌs΍zZ4l SSS1eʔHj v\^)ϮMMMk00#C>H$ Mk.HѸk0X:g\\ƍY>*ZlzEGG-[;v w-M*vXt9tϟ?m4xFނD"aT:uY.\˹wl QCocЉW矹\.ٲUXc?ӆ lmmi*Z bŊ]ׯ_ojj_9Nn|IZlϦv5jԨSN6 w9TTTobbsNrhУXExۼϞ=v˥& ZXXr \P(R)B(11q„ Xk󓒒޽˶%bYq999Hnp5_Sօ˫ǏlڴIS!dllCUhhرc,X@v@ |=S#H>ɉ(ЧO?7nmyyy7n+Vh\ccA::D"Yr%dԩzzz,XA7:mҥk֬] -_w:8t tޝ0q?dqCիW#bbbpF+Wl `w%mllo׺uqF_T~8NHHtH=Tw͙3G& K*j-/^_.);;pig޽{y<ޣG@8qB!am˖-qPWWףGxSNHtYnԩS{Ic1#z-XPb޼y={;;m200ЁȌj'222BE &L@Akaȯ_ZZ6'oE_|||?M2EP{**sε]7!̴QMMц hͼ^z^VVt¢w!׿L?[om>|\?˗3OM]]3x8coҥ}opBܵtك|}}.b֭]6o {͇3744, 3fl޼YC!}%=/^3\ ŋoݺz[$%%qܐt)%:#FuӢE>} 3_ -,,v؁ ̚\kFgϝ;_ms=3F;wY >.\XRR|X:.\иA\\\ƌv-CG.gff>K5V-:uTnn.BNk:>|,/Ǝk.܅2t_ׯ_?,Zqܹsڵ n'Zݻw=<\SSZNAA R3e2١Cpt#HpUDh"kkkKKŋ744t999~5W( &M 9~t-88Xwh#Gu}̙%%%+<{ !|( HMM%bȑ/_ܻwo'_)pe˖6wIɓ'¸su>!aÆfgg.x!dmm.pBRRҒ%K߯_K۷ڵk|y}}=Q8 秦8qYYYi߽Q~bo?YPPn:uyBS1]FޘxoGڿ?ΚP(Mի{S&W(4ZZ !G?(8=:Ul?!J~K~|J@@@gt$''ԔUwʕe˖9::R3rssoݺEa,'$###$$VOO{l[o.B!:Nyy9B[nd픔dddxyy}7l{C^ۛv}}}>~Sl'D$]p!33իW۶m;p@TTMOoNSSBc*^|200 %㲲R iiiiii|rЦMhUU Dr…ׯ744޽[f 4iSUYY) &M:wwUg}×/_O!j;Ŕ`[a#?LRV" Iq\/B޽{T6ʕ+-,,z"~[4iҭ[=z~SE'jӦMB}O={_QQ1`3grP`` ڣ١RB Z# SE QΆ#?O>T堠 KKK J~CzzΝ;i*RM~iiiׯO?~x5?!VZv}y{{T$Uۗ2z蠠 ܵGC'""!J~={j]z!4}tBǎ#>Bh̘14>iҤ'OP ٶmB?D566R"EN<9o w}ɓ'4K+ ~SL<7Ay :tڴi}{l=pW H{:Ak˖-FFF(GaU}ut&LPWWיLPBG0hĈlh @#Fq9pAP(`@+,  !4bĈlr!hBhذa/.h?Bݺultq* ~?>uԼyvE"B\/;;w!B"ܹ׭[wersbmm CAS]]}ĉUV-\pEEE+oo7oB'888,]\D.*w9w\P}!tx{{CO1k׮ms&rti̡O.eB&&&xlUп\@dR/!!ؘ'&&у|3ɵI1+,,l~~~ X?+nnn2X7^_ĉ97&+FLJJd /abbafagpLQ$tɒ@{۶mV9-|VVV X[ٳ?#|7|?;kggBUX___ 7l_-Z: By|>fff^=**ի ܲe ) WX8::>| +W?ݻ˗?EM2ŋxxt0 { ?׏9|pZZڀ` xwqM]Ož*ą nQjZV՟uઢb*ֽ D@PCe>O BHn%7~3p9۷dW :.zѐ!C<<<|pSN]N7 t? "['&BHKK'AHOH!Xv@>>wss=rH aڵׯ_"CSlmmLgqQ\pB ,,,%%@ tWQQ葩SZ[[Bb#QrJt ߄SԄ֕ëg"Ə8n8P\\ bs!p3k֬KSSSM&fIII}!oW_}%Zs,ͱ0f777,++CIT|m;FݸqIGGGfǏ/m#HAu&cٲe?2:!===GfeݺuFFFx "!ϟ5k0L1qD\JNgʔ)Ǐ2:>}Bb?bKTWW󞐑`0mBXTT$G,^^^b4i$\N 7A e111="&á, /{X!˥hIMM4h$''[ZZJKPGGx ]Y`A]]ŋ{ NB>m۷8ڵk{űBܝ?~̙ⷓ$VH!&t`ԩ! 6˗/>}3fMihh?~BөD\ŋ?SUUCEzt 7+ .LNN.--~ Э[(D_ߟdU$rssutt,--l'--B}?OEzt 7SӧO/bbbzNۛvd@.ݷoϟpMMM\.~YfyF䪸ȳvڟ~Iv.\,~;&:z~s`cccRRRhnwo.֬Ycjjf|lNCC7|ӷo˗׷}ã-OMMݺ"rU\ɄUnnoӦMC19{ؙ&ࢨB$'' [md.tԾ'O .D(.@:{]...s:@7oիم|…Za XǏ| .dd2ҦLBv!@7ܹs<BGܹsdN:B={͛7kjj}&ILS{ IDATL166& f͚f\3!t͛7 HH>}Ǝ+(++{1ٳg_~kX:"11QUUU{?͞=b]vM tEbbمBp8III'O& f͚u zA(NI򪯯hdddkkKv!@ΙXZZ BG!ܼysr<'NLNNW[[ V&Lw!t_jj*Ñ0aB(55'@ȿ7o9wd#ցБpl$t*%%HBIIIqqޡŋ#G]^x ,&Lm۶W^v|бBHKKΎ*Bիd" P _`` %HjzzzC9>>Ϗ8m׮]6mz6ٵ(..B/B(>>B䄫Ç;>tBh,K~3+**222ğ=z46VG:!Իwooo?Bpvee対BqppxQCCCLJ t+444???//BtI&ijj]P8l6;??C:>dȐ( MmmmJJ [RXXX=|C:ZdӧG%&&Xӧ]PPvvv=B_rم̙3d]AAA:՝3gNdNyy /^Lv!@q 2oi'44K}2ɓdmmmmyy9rv\\\ &맓\cTUUɮ(. C[xq\\ܧO.DtϞ=[d مf``QRR·B߼yTLN1bСC.(4 2p@uuugϞ]`م PZZʷBd"Gl dqYYBN=zĈx:e݋/իٵ !t `pi_YYwߑ]!ddd;: 鱱d\.t$g``P__v!N455Ν{ak֬!KOO!TSSv!N-[VTTt ֮]GEv!N~ɍ7VZEv! BBCCϞ=[UUEv!۰aȑ#a UB|@ﯦ&.\a PSSSۅ:9rDO'oٲӓBhGYY!v!N7BCC矴4 Rnnŋ7nHv!hT*Bn :YO'o޼|҉NCXhh{ ă\~z s,F]=___MM͘ իlZfcgvx t6o޼(Cv-;w.55u߾} Zv`E.ҥK_xqm Wss?8w\GGGksu+͘1ct+**~7 K!mm !tz…CۓǏ7o 366&u:C@GWWWJN'o޼YUU.Z)##G~:ׯ: Ё+хz*992.]joo|rr[:h{:wΜ9sRiWVVfhhwKYȨРo>}СC/_L&ԬZjɒ%0R׭[Phh(m455IO.-gggUUU;;ϟ?ST˦&b&_lmؖ{فCv…Ç'@yi.PX,VBBرc̚>QnF}m߾wiĈ `٭@իW&&&| !t뛑rY,ߣY|aN͛7} N "S\\laaBG(ÇWRR7Iy޽X8@Q00E?}dnnηB9tдi:KJJ6lO?YYYItCƆo!B2d5)%ɓ鈈J 6ܑ]dڵk%5|%vSh4Zpp0Yȓϟ+++9ѩ]vظcH4tbbbܹpf.ad#Omll:@@>}455ێFR%:>|Xf͊+ &M(8ѣGΔQTGG[|(((:th:=cnn~M:λɒFI.t.\e BOB^ :.1xTr{:QQQ׮];y򤺺$?|𡬬ֶC:#}}l6=={8qHڜ9st:N={6ٵȉѣGw]\x1"czzz&M¥ALAAA5|p92#f[dooob6rӧ-q{O>Ji;Kw||-&5JB.ۣe޼ys]9|}}.g؋'Iy#ĉmfdd0n.8::u55)TjTTANNN~~~kk+I|R 77[!DFF}!dllZlB())H%Ν;Ӛ:=vر۷oR(-xDX<<>BHjjqRSS6C4pNйyҤI&R+0._u tl}||F{㰧wB =@;o߾W^mcc#!t\R__?""BB_/^oܸ!Dz€=~~~SLV t^SSsNn!;wX=*--o-Z-mAlvPP޽{ ^mۖ%VB=Zvv͛7n8bb*//'l:(iӦ;wNI3-pNիwjii]O:u9+++7 W(ׯ^:""b֬YoB`0fϞ|r# Bk.j@QN6166J%wB3f+..NYYJ򯦦fʔ)YYYzzzĉkkk322$=l0 tgXԤ]B:ȱZOO߾}[JdUuu)SJKKoݺ5h r!//A o=z_]?JffСCH:)Dž Lzybrb׮]gϞ1cƹs.KpԴ`ݻw\r˗/9B7Jnni j̙>LHH `*AEѪ\n6449lȞ?>k֬ʛ7o]PPP&&&cƌt*ڿ+W=ZYY9''GVAE$CҀb\rƌYYY2qO{:4mΜ9#ooCEFFFEE]Q@ť7ydv!F|TVVv) EGt:?dWlC\]])q!??V???kAEEEnnn+W OOO "AƎ?vXhiiYvy dWOAECh4󟖖R5jԁ<9x`R P\L&sK,qqqqqqYdL&ae455mڴՕNgff88m9so rÇڪaaa/_Ė|2,,LUUU[[;<<Ǐի{immP,o߾ TWWpuuuMMͰoJS԰0Mz@E eee==*ϯSVV z9^0p:>jԨ\:@=}4((NFFF nmmmdd!N z\zuڑ r<BȳӧSTcczک466RӧOm, !+*:@>eddL8!4hРflnn8qbff+//_ͥKƌ1bĥKl6x>1c\tIoޫW/CCØ܋E:@N옘aÆ!/]p$9s%GGGаa6pbbbLLLo.25&&!4}tA vgkkNMMuppPRR 22dFFFQ(ӧ߹sJ )#B0a;}t\m Wcc;V^˗/crHzʪ'\*ھxӧOJJJ!!!dWį8$$DIII__?""ӧOdW$] t(// RSSkaJ:aݸԴɮHZ@͛0 J+VeeeDDq ՞={uիWDDćȮH|ݸ={FvEdRɓ'شX:yűc _O555KK dggPER}||Sލ/_Μ9SGGb BHlTDnޞ7k566`k}d~?۷/J믿D655EEEƕ#Nk=ջQUUe``6d###%W"eo++\itVbb"BhРA◄]S3fLrrm ڰa˱-,,$X@ t).X܌9Sx6^K.1Dk0_-ǏB+ndb'N>|3\OOO 3f[V)..F8d:Jrvƌ#F8qk?MF@rX'Nϟ? #++S:'ꮯOJJ;wmBxzzfee1 cc۟8q7ٱ5Fa-B(88XkWX)SSSTFF.Zm 4ɓ' idd$ķ}ƍMMM%'BD7==-:\.h޽$MKK۷/B(<<ߖڒ7 VTTF:tH+B3txܹ9r$~ud؞3|hjj5j֭[\'ܹs!S @IIIXXJ>}"""%-B!_iTWWGDDGEE%,,D[ .q8nׯ_GHhc)--m+L[+t222B666_eeeٸJKKqOѣG---?rlѣG &`߿UQQ y5^-766&%%ukZL&355[˗,2>>~ %..\ׯCBBTTTtuu#""޿c|z7222Κ*ݶsssB/^YTT$~.:;;uJAIDAT{xxN722NKK*LQQ6W޽oNFW_J\vPAA6@^ú&ݻww=sY~D*څϟBׯ_'0 SؽQ2dF 8'_7. |yPP1O`B֭[NNN!Ǐ X622NURaa!a 22G'{ ݂x]r7n\VV׷ƕ'N1X)ccH)::`kk?\ |BXg#G&%%֍!4qD3'33}a``%1a]LL –!&L`0$T"UV }777nPb2tnn iMMM۷on#O:pԩƥ(ܮ0aĺ.[VTTZjd;d PX`ɓ' (.0te˖M2ٳg% 2݄Nccٳg ('''??!C|JvQLݏ_xj<)++ q8u-[TUU\~ӧE%ll;;aÆ:uJ5YrϞ=q '( =GѶlLBBvc1${:iӦh4\ZZ333}||6l؀ zvsO<9zR&M;v,NȈ=ճб^tMjjj$TNϟ?5jTuuuRRRjj E"""8κu$Q B^ 2dH~~3gx N޽|...f!. GD]yϞ=JJJwf Z[[?|@vE@>xxӧO󵴴B@$lm۶-]t͚5d P(Ǐ7668Xlٲɓ'?{%'}ݻwѣG]WA0ovvv/^Ɂ)v߾}{BB. UTTܻw/..pc1 ^ -Zɓ'&&&x5 ۷8p@[[{pc1ߧͅˮ䪫۵k9ڵkWXAvQ o \\\ L@]v555}aaaz"(s ^|8v3g"a7_eeUV^OvQ333s]xqǎ7:r-[6ugϞm߾H'Loׯ_Dd'''???[[[ltKuʕ_9s222$ `0\]]'M}x H? N/}᯾/˓VÇ'MNR FRRѣ. H0th4ɓ']\\BG$i9V\\;r>$%%]= A)++߃ >> i*B֭Qmɟ>}MC9sFszc͛6m搨EE$DztDMa|رfZr]=%iW>aaa؁^uuʁȮU<|L0̙3dW$Azzz!~Ǐ]BЉ FX!O:,`xl0l3g͛0`@nnnNN-33֭[FFF?=Q>'))iFFF!*l2;;***ƍ۽{7Bĉd@gؤ$]vU1&O.c dcO[IIIuuumw#G]tА!C.I8qbڴimblv-XNRIݻwB| م= &`00LPSSSfffۅ=ںuߍ9o޼YlYUUB1%%{=f9''gΜ9CmzKKKVVT1-,,fϞիW,\1nCɝqcW/ϟ?>566v[0w$wUƷ~>rlDIdй#| bNطo߾}.I@.A P:BA P:BA P:BA P:B9r/a@[EBBBhh(YHU (R20@A9 t B@>82̟IENDB`tins-1.32.1/Rakefile0000644000004100000410000000201114353307475014255 0ustar www-datawww-data# vim: set filetype=ruby et sw=2 ts=2: require 'gem_hadar' GemHadar do name 'tins' author 'Florian Frank' email 'flori@ping.de' homepage "https://github.com/flori/#{name}" summary 'Useful stuff.' description 'All the stuff that isn\'t good/big enough for a real library.' test_dir 'tests' test_files.concat Dir["#{test_dir}/*_test.rb"] ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', '.rvmrc', 'coverage', '.rbx', '.AppleDouble', '.DS_Store', 'tags', '.bundle', '.byebug_history' package_ignore '.all_images.yml', '.tool-versions', '.gitignore', 'VERSION', '.utilsrc', '.rspec', 'TODO', *Dir.glob('.github/**/*', File::FNM_DOTMATCH) readme 'README.md' licenses << 'MIT' required_ruby_version '>= 2.0' development_dependency 'utils' development_dependency 'all_images' development_dependency 'debug' development_dependency 'term-ansicolor' development_dependency 'test-unit', '~>3.1' development_dependency 'simplecov' dependency 'sync' end tins-1.32.1/lib/0000755000004100000410000000000014353307475013364 5ustar www-datawww-datatins-1.32.1/lib/tins/0000755000004100000410000000000014353307475014341 5ustar www-datawww-datatins-1.32.1/lib/tins/hash_symbolize_keys_recursive.rb0000644000004100000410000000230714353307475023032 0ustar www-datawww-datarequire 'tins/thread_local' module Tins module HashSymbolizeKeysRecursive extend Tins::ThreadLocal thread_local :seen def symbolize_keys_recursive(circular: nil) self.seen = {} _symbolize_keys_recursive(self, circular: circular) ensure self.seen = nil end def symbolize_keys_recursive!(circular: nil) replace symbolize_keys_recursive(circular: circular) end private def _symbolize_keys_recursive(object, circular: nil) case when seen[object.__id__] object = circular when Hash === object seen[object.__id__] = true new_object = object.class.new seen[new_object.__id__] = true object.each do |k, v| new_object[k.to_s.to_sym] = _symbolize_keys_recursive(v, circular: circular) end object = new_object when Array === object seen[object.__id__] = true new_object = object.class.new(object.size) seen[new_object.__id__] = true object.each_with_index do |v, i| new_object[i] = _symbolize_keys_recursive(v, circular: circular) end object = new_object end object end end end require 'tins/alias' tins-1.32.1/lib/tins/terminal.rb0000644000004100000410000000127314353307475016504 0ustar www-datawww-databegin require 'io/console' rescue LoadError end module Tins module Terminal module_function def winsize if IO.respond_to?(:console) console = IO.console if console.respond_to?(:winsize) console.winsize else [] end else [] end end def rows winsize[0] || `stty size 2>/dev/null`.split[0].to_i.nonzero? || `tput lines 2>/dev/null`.to_i.nonzero? || 25 end def lines rows end def columns winsize[1] || `stty size 2>/dev/null`.split[1].to_i.nonzero? || `tput cols 2>/dev/null`.to_i.nonzero? || 80 end def cols columns end end end tins-1.32.1/lib/tins/string_version.rb0000644000004100000410000000422514353307475017744 0ustar www-datawww-datamodule Tins module StringVersion LEVELS = [ :major, :minor, :build, :revision ].each_with_index. each_with_object({}) { |(k, v), h| h[k] = v }.freeze SYMBOLS = LEVELS.invert.freeze class Version include Comparable def initialize(string) string =~ /\A\d+(\.\d+)*\z/ or raise ArgumentError, "#{string.inspect} isn't a version number" @version = string.frozen? ? string.dup : string end LEVELS.each do |symbol, level| define_method(symbol) do self[level] end define_method("#{symbol}=") do |new_level| self[level] = new_level end end def bump(level = array.size - 1) level = level_of(level) self[level] += 1 for l in level.succ..3 self[l] &&= 0 end self end def level_of(specifier) if specifier.respond_to?(:to_sym) LEVELS.fetch(specifier) else specifier end end def [](level) array[level_of(level)] end def []=(level, value) level = level_of(level) value = value.to_i value >= 0 or raise ArgumentError, "version numbers can't contain negative numbers like #{value}" a = array a[level] = value a.map!(&:to_i) @version.replace a * ?. end def succ! self[-1] += 1 self end def pred! self[-1] -= 1 self end def <=>(other) pairs = array.zip(other.array) pairs.map! { |a, b| [ a.to_i, b.to_i ] } a, b = pairs.transpose a <=> b end def ==(other) (self <=> other).zero? end def array @version.split(?.).map(&:to_i) end alias to_a array def to_s @version end def initialize_copy(source) super @version = source.instance_variable_get(:@version).dup end alias inspect to_s end def version Version.new(self) end end def self.StringVersion(string) StringVersion::Version.new(string.to_str) end end require 'tins/alias' tins-1.32.1/lib/tins/version.rb0000644000004100000410000000041014353307475016346 0ustar www-datawww-datamodule Tins # Tins version VERSION = '1.32.1' VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc: VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: VERSION_BUILD = VERSION_ARRAY[2] # :nodoc: end tins-1.32.1/lib/tins/timed_cache.rb0000644000004100000410000000226314353307475017116 0ustar www-datawww-dataclass TimedCache class Value < Struct.new(:value, :timestamp) def self.json_create(hash) new(*hash.values_at('value', 'timestamp')) end def as_json(*) super | { JSON.create_id => self.class.name } end end def initialize(name, ttl: 60, jitter: 1..5, &block) @name = name @ttl = ttl @jitter = jitter block or raise ArgumentError, 'block is required' @block = block @redis = Redis.new # RedisPool::Pool.connection(:timed_cache, configuration: :redis) end def namespaced(key) "timed_cache:#{key}" end def value now = Time.now if stored = stored_value if (now - @ttl).to_i >= stored.timestamp Thread.new { sleep @jitter if stored_value.timestamp <= stored.timestamp @redis.set namespaced(@name), new_value(now).to_json end } end stored.value else nv = new_value(now) @redis.set namespaced(@name), nv.to_json nv.value end end def new_value(now) Value.new(@block.(), now.to_i) end def stored_value @redis.get(namespaced(@name)).full? { |s| ::JSON.parse(s, create_additions: true) rescue nil } end end tins-1.32.1/lib/tins/to_proc.rb0000644000004100000410000000026214353307475016333 0ustar www-datawww-datamodule Tins module ToProc # :nocov: def to_proc lambda do |obj, *args| obj.__send__(self, *args[0..-1]) end end end end require 'tins/alias' tins-1.32.1/lib/tins/if_predicate.rb0000644000004100000410000000012714353307475017304 0ustar www-datawww-datamodule Tins module IfPredicate def if? self ? self : nil end end end tins-1.32.1/lib/tins/alias.rb0000644000004100000410000000001514353307475015753 0ustar www-datawww-dataSpruz = Tins tins-1.32.1/lib/tins/once.rb0000644000004100000410000000105714353307475015615 0ustar www-datawww-datamodule Tins module Once include File::Constants module_function def only_once(lock_filename = nil, locking_constant = nil) lock_filename ||= $0 locking_constant ||= LOCK_EX f = File.new(lock_filename, RDONLY) f.flock(locking_constant) and yield ensure if f f.flock LOCK_UN f.close end end def try_only_once(lock_filename = nil, locking_constant = nil, &block) only_once(lock_filename, locking_constant || LOCK_EX | LOCK_NB, &block) end end end require 'tins/alias' tins-1.32.1/lib/tins/temp_io_enum.rb0000644000004100000410000000122214353307475017343 0ustar www-datawww-datarequire 'tins/temp_io' module Tins module TempIO class Enum < Enumerator include Tins::TempIO def initialize(chunk_size: 2 ** 16, filename: nil, &content_proc) content_proc or raise ArgumentError, 'need a content proc as block argument' super() do |y| temp_io(name: 'some-stream', content: content_proc) do |file| until file.eof? y.yield file.read(chunk_size) end end end.tap do |enum| if filename enum.define_singleton_method(:filename) do filename end end end end end end end tins-1.32.1/lib/tins/go.rb0000644000004100000410000000454114353307475015277 0ustar www-datawww-datamodule Tins module GO module EnumerableExtension def push(argument) @arguments ||= [] @arguments.push argument self end alias << push def each(&block) @arguments.each(&block) self end include Enumerable end module_function # Parses the argument array _args_, according to the pattern _s_, to # retrieve the single character command line options from it. If _s_ is # 'xy:' an option '-x' without an option argument is searched, and an # option '-y foo' with an option argument ('foo'). To disable the '-x' # option, pass '~x'. # # The _defaults_ argument specifies default values for the options. # # An option hash is returned with all found options set to true or the # found option argument. def go(s, args = ARGV, defaults: {}) d = defaults || {} b, v = s.scan(/(.)(:?)/).inject([ {}, {} ]) { |t, (o, a)| a = a == ?: t[a ? 1 : 0][o] = a ? nil : false t } b.each_key do |k| d.key?(k) or next if [ 0, false, nil ].include?(d[k]) b[k] = false elsif d[k].respond_to?(:to_int) b[k] = d[k].to_int else b[k] = 1 end end v.each_key do |k| d.key?(k) or next if [ 0, false, nil ].include?(d[k]) v[k] = nil else v[k] = d[k].to_s end end r = [] while a = args.shift /\A-(?

.+)/ =~ a or (r << a; next) until p == '' o = p.slice!(0, 1) if v.key?(o) if p.empty? && args.empty? r << a break 1 elsif p == '' a = args.shift else a = p end if v[o].nil? || !(EnumerableExtension === v[o]) a = a.dup a.extend EnumerableExtension a << a v[o] = a else v[o] << a end break elsif b.key?(o) if b[o] b[o] += 1 else b[o] = 1 end else r << a end end && break end r.reject! { |a| (b[p] = false) || true if /\A~(?

.)/ =~ a } args.replace r b.merge(v) end end end require 'tins/alias' tins-1.32.1/lib/tins/to.rb0000644000004100000410000000023414353307475015307 0ustar www-datawww-datamodule Tins module To def to(string) shift_width = (string[/\A\s*/]).size string.gsub(/^[^\S\n]{0,#{shift_width}}/, '') end end end tins-1.32.1/lib/tins/date_time_dummy.rb0000644000004100000410000000176314353307475020043 0ustar www-datawww-datarequire 'date' module Tins module DateTimeDummy def self.included(modul) class << modul alias really_now now remove_method :now rescue nil def dummy=(value) if value.respond_to?(:to_str) value = DateTime.parse(value.to_str) elsif value.respond_to?(:to_datetime) value = value.to_datetime end @dummy = value end def dummy(value = nil) if value.nil? if defined?(@dummy) @dummy end else begin old_dummy = @dummy self.dummy = value yield ensure self.dummy = old_dummy end end end def now if dummy dummy.dup elsif caller.first =~ /`now`/ really_now else really_now end end end super end end end require 'tins/alias' tins-1.32.1/lib/tins/range_plus.rb0000644000004100000410000000016014353307475017022 0ustar www-datawww-datamodule Tins module RangePlus def +(other) to_a + other.to_a end end end require 'tins/alias' tins-1.32.1/lib/tins/partial_application.rb0000644000004100000410000000153314353307475020707 0ustar www-datawww-datamodule Tins module PartialApplication # If this module is included into a Proc (or similar object), it tampers # with its Proc#arity method. def self.included(modul) modul.module_eval do old_arity = instance_method(:arity) define_method(:arity) do defined?(@__arity__) or old_arity.bind(self).call end end super end # Create a partial application of this Proc (or similar object) using # _args_ as the already applied arguments. def partial(*args) if args.empty? dup elsif args.size > arity raise ArgumentError, "wrong number of arguments (#{args.size} for #{arity})" else f = lambda { |*b| call(*(args + b)) } f.instance_variable_set :@__arity__, arity - args.size f end end end end require 'tins/alias' tins-1.32.1/lib/tins/concern.rb0000644000004100000410000000144414353307475016320 0ustar www-datawww-datamodule Tins module Concern def self.extended(base) base.instance_variable_set("@_dependencies", []) end def append_features(base) if base.instance_variable_defined?("@_dependencies") base.instance_variable_get("@_dependencies") << self false else return false if base < self @_dependencies.each { |dep| base.send(:include, dep) } super base.extend const_get("ClassMethods") if const_defined?("ClassMethods") base.class_eval(&@_included_block) if instance_variable_defined?("@_included_block") Thread.current[:tin_concern_args] = nil true end end def included(base = nil, &block) if base.nil? @_included_block = block else super end end end end tins-1.32.1/lib/tins/sexy_singleton.rb0000644000004100000410000000317314353307475017744 0ustar www-datawww-datarequire 'singleton' module Tins SexySingleton = Singleton.dup module SexySingleton module SingletonClassMethods end end class << SexySingleton alias __old_singleton_included__ included if RUBY_VERSION < "2.7" def included(klass) __old_singleton_included__(klass) (class << klass; self; end).class_eval do if Object.method_defined?(:respond_to_missing?) def respond_to_missing?(name, *args) instance.respond_to?(name) || super end else def respond_to?(name, *args) instance.respond_to?(name) || super end end def method_missing(name, *args, &block) if instance.respond_to?(name) instance.__send__(name, *args, &block) else super end end end super end else def included(klass) __old_singleton_included__(klass) (class << klass; self; end).class_eval do if Object.method_defined?(:respond_to_missing?) def respond_to_missing?(name, *args, **kwargs) instance.respond_to?(name) || super end else def respond_to?(name, *args, **kwargs) instance.respond_to?(name) || super end end def method_missing(name, *args, **kwargs, &block) if instance.respond_to?(name) instance.__send__(name, *args, **kwargs, &block) else super end end end super end end end end tins-1.32.1/lib/tins/xt/0000755000004100000410000000000014353307475014774 5ustar www-datawww-datatins-1.32.1/lib/tins/xt/hash_symbolize_keys_recursive.rb0000644000004100000410000000017214353307475023463 0ustar www-datawww-datarequire 'tins/hash_symbolize_keys_recursive' module Tins class ::Hash include HashSymbolizeKeysRecursive end end tins-1.32.1/lib/tins/xt/string_version.rb0000644000004100000410000000014214353307475020371 0ustar www-datawww-datamodule Tins require 'tins/string_version' class ::String include StringVersion end end tins-1.32.1/lib/tins/xt/if_predicate.rb0000644000004100000410000000014214353307475017734 0ustar www-datawww-datarequire 'tins/if_predicate' module Tins class ::Object include Tins::IfPredicate end end tins-1.32.1/lib/tins/xt/to.rb0000644000004100000410000000007614353307475015746 0ustar www-datawww-datamodule Tins class ::Object include ::Tins::To end end tins-1.32.1/lib/tins/xt/date_time_dummy.rb0000644000004100000410000000014314353307475020465 0ustar www-datawww-datarequire 'tins/date_time_dummy' module Tins class ::DateTime include DateTimeDummy end end tins-1.32.1/lib/tins/xt/range_plus.rb0000644000004100000410000000033014353307475017454 0ustar www-datawww-datarequire 'tins/range_plus' module Tins class ::Range if method_defined?(:+) warn "#{self}#+ already defined, didn't include at #{__FILE__}:#{__LINE__}" else include RangePlus end end end tins-1.32.1/lib/tins/xt/partial_application.rb0000644000004100000410000000023714353307475021342 0ustar www-datawww-datarequire 'tins/partial_application' module Tins class ::Proc include PartialApplication end class ::Method include PartialApplication end end tins-1.32.1/lib/tins/xt/concern.rb0000644000004100000410000000053614353307475016754 0ustar www-datawww-datarequire 'tins/concern' module Tins module Concern module ModuleMixin def tins_concern_configure(*args) Thread.current[:tin_concern_args] = args self end def tins_concern_args Thread.current[:tin_concern_args] end end end class ::Module include Tins::Concern::ModuleMixin end end tins-1.32.1/lib/tins/xt/sexy_singleton.rb0000644000004100000410000000007014353307475020370 0ustar www-datawww-datamodule Tins ::SexySingleton = Tins::SexySingleton end tins-1.32.1/lib/tins/xt/extract_last_argument_options.rb0000644000004100000410000000017314353307475023474 0ustar www-datawww-datarequire 'tins/extract_last_argument_options' module Tins class ::Array include ExtractLastArgumentOptions end end tins-1.32.1/lib/tins/xt/method_description.rb0000644000004100000410000000054114353307475021204 0ustar www-datawww-datarequire 'tins/method_description' module Tins class ::UnboundMethod include MethodDescription alias to_s description def inspect "#<#{self.class}: #{description}>" end end class ::Method include MethodDescription alias to_s description def inspect "#<#{self.class}: #{description}>" end end end tins-1.32.1/lib/tins/xt/time_freezer.rb0000644000004100000410000000043014353307475017776 0ustar www-datawww-datarequire 'tins/xt/time_dummy' require 'tins/xt/date_time_dummy' require 'tins/xt/date_dummy' module Tins::TimeFreezer def self.freeze(time) Time.dummy(time) do DateTime.dummy(time) do Date.dummy(time) do yield end end end end end tins-1.32.1/lib/tins/xt/ask_and_send.rb0000644000004100000410000000014114353307475017726 0ustar www-datawww-datarequire 'tins/ask_and_send' module Tins class ::Object include Tins::AskAndSend end end tins-1.32.1/lib/tins/xt/deep_dup.rb0000644000004100000410000000013214353307475017102 0ustar www-datawww-datarequire 'tins/deep_dup' module Tins class ::Object include Tins::DeepDup end end tins-1.32.1/lib/tins/xt/dslkit.rb0000644000004100000410000000072014353307475016612 0ustar www-datawww-datarequire 'tins' module Tins class ::Module include Tins::Constant include Tins::DSLAccessor include Tins::ClassMethod include Tins::Delegate include Tins::ParameterizedModule include Tins::FromModule end class ::Object include Tins::ThreadLocal include Tins::ThreadGlobal include Tins::Interpreter include Tins::Deflect include Tins::ThreadLocal include Tins::Eigenclass include Tins::BlockSelf end end tins-1.32.1/lib/tins/xt/file_binary.rb0000644000004100000410000000013014353307475017576 0ustar www-datawww-datarequire 'tins/file_binary' module Tins class ::File include FileBinary end end tins-1.32.1/lib/tins/xt/p.rb0000644000004100000410000000011514353307475015555 0ustar www-datawww-datarequire 'tins/p' module Tins class ::Object include Tins::P end end tins-1.32.1/lib/tins/xt/null.rb0000644000004100000410000000016214353307475016272 0ustar www-datawww-datarequire 'tins/null' module Tins ::NULL = Tins::NULL class ::Object include Tins::Null::Kernel end end tins-1.32.1/lib/tins/xt/case_predicate.rb0000644000004100000410000000014714353307475020256 0ustar www-datawww-datarequire 'tins/case_predicate' module Tins class ::Object include Tins::CasePredicate end end tins-1.32.1/lib/tins/xt/attempt.rb0000644000004100000410000000013114353307475016772 0ustar www-datawww-datarequire 'tins/attempt' module Tins class ::Object include Tins::Attempt end end tins-1.32.1/lib/tins/xt/string.rb0000644000004100000410000000025014353307475016624 0ustar www-datawww-datamodule Tins require 'tins/xt/string_camelize' require 'tins/xt/string_underscore' require 'tins/xt/string_version' require 'tins/xt/string_byte_order_mark' end tins-1.32.1/lib/tins/xt/count_by.rb0000644000004100000410000000020414353307475017137 0ustar www-datawww-datarequire 'tins/count_by' module Tins module ::Enumerable include CountBy end class ::Array include CountBy end end tins-1.32.1/lib/tins/xt/subhash.rb0000644000004100000410000000023514353307475016756 0ustar www-datawww-datarequire 'tins/subhash' module Tins class ::Hash include Tins::Subhash def subhash!(*patterns) replace subhash(*patterns) end end end tins-1.32.1/lib/tins/xt/responding.rb0000644000004100000410000000013714353307475017472 0ustar www-datawww-datarequire 'tins/responding' module Tins class ::Object include Tins::Responding end end tins-1.32.1/lib/tins/xt/annotate.rb0000644000004100000410000000010314353307475017124 0ustar www-datawww-datarequire 'tins/annotate' class Module include Tins::Annotate end tins-1.32.1/lib/tins/xt/string_underscore.rb0000644000004100000410000000014714353307475021062 0ustar www-datawww-datamodule Tins require 'tins/string_underscore' class ::String include StringUnderscore end end tins-1.32.1/lib/tins/xt/irb.rb0000644000004100000410000000065414353307475016102 0ustar www-datawww-datarequire 'irb' module Tins IRB = ::IRB module ::IRB def self.examine(binding = TOPLEVEL_BINDING) setup nil workspace = WorkSpace.new binding irb = Irb.new workspace @CONF[:MAIN_CONTEXT] = irb.context catch(:IRB_EXIT) { irb.eval_input } rescue Interrupt exit end end class ::Object def examine(binding = TOPLEVEL_BINDING) IRB.examine(binding) end end end tins-1.32.1/lib/tins/xt/deep_const_get.rb0000644000004100000410000000013714353307475020304 0ustar www-datawww-datarequire 'tins/deep_const_get' module Tins class ::Object include DeepConstGet end end tins-1.32.1/lib/tins/xt/blank.rb0000644000004100000410000000174414353307475016416 0ustar www-datawww-datamodule Tins module Blank module Object def blank? respond_to?(:empty?) ? empty? : !self end def present? !blank? end end module NilClass def blank? true end end module FalseClass def blank? true end end module TrueClass def blank? false end end module Array def self.included(modul) modul.module_eval do alias_method :blank?, :empty? end end end module Hash def self.included(modul) modul.module_eval do alias_method :blank?, :empty? end end end module String def blank? self !~ /\S/ end end module Numeric def blank? false end end end end unless Object.respond_to?(:blank?) for k in Tins::Blank.constants Object.const_get(k).class_eval do include Tins::Blank.const_get(k) end end end tins-1.32.1/lib/tins/xt/expose.rb0000644000004100000410000000010114353307475016614 0ustar www-datawww-datarequire 'tins/expose' class ::Object include Tins::Expose end tins-1.32.1/lib/tins/xt/uniq_by.rb0000644000004100000410000000027114353307475016767 0ustar www-datawww-datarequire 'tins/uniq_by' module Tins module ::Enumerable include UniqBy end class ::Array include UniqBy def uniq_by!(&b) replace uniq_by(&b) end end end tins-1.32.1/lib/tins/xt/proc_prelude.rb0000644000004100000410000000013714353307475020005 0ustar www-datawww-datarequire 'tins/proc_prelude' module Tins class ::Proc extend Tins::ProcPrelude end end tins-1.32.1/lib/tins/xt/string_camelize.rb0000644000004100000410000000014314353307475020476 0ustar www-datawww-datamodule Tins require 'tins/string_camelize' class ::String include StringCamelize end end tins-1.32.1/lib/tins/xt/require_maybe.rb0000644000004100000410000000014414353307475020151 0ustar www-datawww-datarequire 'tins/require_maybe' module Tins class ::Object include Tins::RequireMaybe end end tins-1.32.1/lib/tins/xt/implement.rb0000644000004100000410000000010514353307475017307 0ustar www-datawww-datarequire 'tins/implement' class Module include Tins::Implement end tins-1.32.1/lib/tins/xt/time_dummy.rb0000644000004100000410000000012614353307475017471 0ustar www-datawww-datarequire 'tins/time_dummy' module Tins class ::Time include TimeDummy end end tins-1.32.1/lib/tins/xt/date_dummy.rb0000644000004100000410000000012614353307475017450 0ustar www-datawww-datarequire 'tins/date_dummy' module Tins class ::Date include DateDummy end end tins-1.32.1/lib/tins/xt/proc_compose.rb0000644000004100000410000000014014353307475020004 0ustar www-datawww-datarequire 'tins/proc_compose' module Tins class ::Proc include Tins::ProcCompose end end tins-1.32.1/lib/tins/xt/hash_union.rb0000644000004100000410000000032614353307475017455 0ustar www-datawww-datarequire 'tins/hash_union' module Tins class ::Hash if method_defined?(:|) warn "#{self}#| already defined, didn't include at #{__FILE__}:#{__LINE__}" else include HashUnion end end end tins-1.32.1/lib/tins/xt/write.rb0000644000004100000410000000020314353307475016446 0ustar www-datawww-datarequire 'tins/write' module Tins #class ::Object # include Tins::Write #end class ::IO extend Tins::Write end end tins-1.32.1/lib/tins/xt/string_byte_order_mark.rb0000644000004100000410000000016014353307475022054 0ustar www-datawww-datamodule Tins require 'tins/string_byte_order_mark' class ::String include StringByteOrderMark end end tins-1.32.1/lib/tins/xt/named.rb0000644000004100000410000000102214353307475016400 0ustar www-datawww-datarequire 'tins/xt/string_version' class Object def named(name, method, *args, &named_block) extend Module.new { define_method(name) do |*rest, &block| block = named_block if named_block __send__(method, *(args + rest), &block) end } end end class Module def named(name, method, *args, &named_block) include Module.new { define_method(name) do |*rest, &block| block = named_block if named_block __send__(method, *(args + rest), &block) end } end end tins-1.32.1/lib/tins/xt/secure_write.rb0000644000004100000410000000022614353307475020021 0ustar www-datawww-datarequire 'tins/secure_write' module Tins #class ::Object # include Tins::SecureWrite #end class ::IO extend Tins::SecureWrite end end tins-1.32.1/lib/tins/xt/full.rb0000644000004100000410000000177414353307475016274 0ustar www-datawww-datarequire 'tins/xt/blank' module Tins module Full # Returns the object if it isn't blank (as in Object#blank?), otherwise it # returns nil. If a block was given as an argument and the object isn't # blank, the block is executed with the object as its first argument. If an # argument +dispatch+ was given and the object wasn't blank the method # given by dispatch is called on the object. This is the same as # foo.full?(&:bar) in the previous block form. def full?(dispatch = nil, *args) if blank? obj = nil #elsif Module === dispatch # TODO # dispatch.found?(self) elsif dispatch obj = __send__(dispatch, *args) obj = nil if obj.blank? else obj = self end if block_given? and obj yield obj else obj end end def all_full? if respond_to?(:all?) && all?(&:full?) block_given? ? yield(self) : self end end end class ::Object include Full end end tins-1.32.1/lib/tins/xt/temp_io.rb0000644000004100000410000000010214353307475016746 0ustar www-datawww-datarequire 'tins/temp_io' class ::Object include Tins::TempIO end tins-1.32.1/lib/tins/xt/complete.rb0000644000004100000410000000013314353307475017126 0ustar www-datawww-datarequire 'tins/complete' module Tins class ::Object include Tins::Complete end end tins-1.32.1/lib/tins/extract_last_argument_options.rb0000644000004100000410000000047314353307475023044 0ustar www-datawww-datamodule Tins module ExtractLastArgumentOptions def extract_last_argument_options last_argument = last if last_argument.respond_to?(:to_hash) and options = last_argument.to_hash.dup then return self[0..-2], options else return dup, {} end end end end tins-1.32.1/lib/tins/method_description.rb0000644000004100000410000000575314353307475020563 0ustar www-datawww-datamodule Tins module MethodDescription class Parameters class Parameter < Struct.new(:type, :name) def ==(other) type == other.type end def inspect "#<#{self.class} #{to_s.inspect}>" end end class RestParameter < Parameter def to_s "*#{name}" end end class KeyrestParameter < Parameter def to_s "**#{name}" end end class ReqParameter < Parameter def to_s name.to_s end end class OptParameter < Parameter def to_s "#{name}=?" end end class KeyParameter < Parameter def to_s "#{name}:?" end end class KeyreqParameter < Parameter def to_s "#{name}:" end end class BlockParameter < Parameter def to_s "&#{name}" end end class GenericParameter < Parameter def to_s [ name, type ] * ?: end end def self.build(type, name) parameter_classname = "#{type.to_s.capitalize}Parameter" parameter_class = if const_defined? parameter_classname const_get parameter_classname else GenericParameter end parameter_class.new(type, name) end end class Signature def initialize(*parameters) @parameters = parameters end attr_reader :parameters def eql?(other) @parameters.eql? other.parameters end def ==(other) @parameters == other.parameters end def ===(method) self == method.signature end def to_s @parameters * ?, end def inspect "#<#{self.class} (#{to_s})>" end end def signature description style: :parameters end def description(style: :namespace) valid_styles = %i[ namespace name parameters ] valid_styles.include?(style) or raise ArgumentError, "style has to be one of #{valid_styles * ', '}" if respond_to?(:parameters) generated_name = 'x0' parameter_array = parameters.map { |p_type, p_name| unless p_name generated_name = generated_name.succ p_name = generated_name end Parameters.build(p_type, p_name) } signature = Signature.new(*parameter_array) if style == :parameters return signature end end result = '' if style == :namespace if owner <= Module result << receiver.to_s << ?. # XXX Better to use owner here as well? else result << owner.name.to_s << ?# end end if %i[ namespace name ].include?(style) result << name.to_s << '(' end result << (signature || arity).to_s if %i[ namespace name ].include?(style) result << ?) end result end end end tins-1.32.1/lib/tins/lines_file.rb0000644000004100000410000000473614353307475017011 0ustar www-datawww-datamodule Tins class LinesFile module LineExtension attr_reader :line_number def filename lines_file.filename.dup end end def self.for_filename(filename, line_number = nil) obj = new(File.readlines(filename), line_number) obj.filename = filename obj end def self.for_file(file, line_number = nil) obj = new(file.readlines, line_number) obj.filename = file.path obj end def self.for_lines(lines, line_number = nil) new(lines, line_number) end def initialize(lines, line_number = nil) @lines = lines @lines.each_with_index do |line, i| line.extend LineExtension line.instance_variable_set :@line_number, i + 1 line.instance_variable_set :@lines_file, self end instance_variable_set :@line_number, line_number || (@lines.empty? ? 0 : 1) end attr_accessor :filename attr_reader :line_number def rewind self.line_number = 1 self end def next! old = line_number self.line_number += 1 line_number > old ? self : nil end def previous! old = line_number self.line_number -= 1 line_number < old ? self : nil end def line_number=(number) number = number.to_i if number > 0 && number <= last_line_number @line_number = number end end def last_line_number @lines.size end def empty? @lines.empty? end def each(&block) empty? and return self old_line_number = line_number 1.upto(last_line_number) do |number| self.line_number = number block.call(line) end self ensure self.line_number = old_line_number end include Enumerable def line index = line_number - 1 @lines[index] if index >= 0 end def file_linenumber "#{filename}:#{line_number}" end def match_backward(regexp, previous_after_match = false) begin if line =~ regexp previous_after_match and previous! return $~.captures end end while previous! end def match_forward(regexp, next_after_match = false) begin if line =~ regexp next_after_match and next! return $~.captures end end while next! end def to_s "#{line_number} #{line.chomp}" end def inspect "#<#{self.class}: #{to_s.inspect}>" end end end require 'tins/alias' tins-1.32.1/lib/tins/duration.rb0000644000004100000410000000354714353307475016524 0ustar www-datawww-datamodule Tins class Duration include Comparable def initialize(seconds) @negative = seconds < 0 seconds = seconds.abs @original_seconds = seconds @days, @hours, @minutes, @seconds, @fractional_seconds = [ 86_400, 3600, 60, 1, 0 ].inject([ [], seconds ]) {|(r, s), d| if d > 0 dd, rest = s.divmod(d) r << dd [ r, rest ] else r << s end } end def to_f @original_seconds.to_f end def <=>(other) to_f <=> other.to_f end def negative? @negative end def days? @days > 0 end def hours? @hours > 0 end def minutes? @minutes > 0 end def seconds? @seconds > 0 end def fractional_seconds? @fractional_seconds > 0 end def format(template = '%S%d+%h:%m:%s.%f', precision: nil) result = template.gsub(/%[DdhmSs]/) { |directive| case directive when '%S' then ?- if negative? when '%d' then @days when '%h' then '%02u' % @hours when '%m' then '%02u' % @minutes when '%s' then '%02u' % @seconds when '%D' then format_smart end } if result.include?('%f') if precision fractional_seconds = "%.#{precision}f" % @fractional_seconds else fractional_seconds = '%f' % @fractional_seconds end result.gsub!('%f', fractional_seconds[2..-1]) end result end def to_s format_smart end private def format_smart template = '%h:%m:%s' precision = nil if days? template.prepend '%d+' end if fractional_seconds? template << '.%f' precision = 3 end template.prepend '%S' format template, precision: precision end end end tins-1.32.1/lib/tins/ask_and_send.rb0000644000004100000410000000130314353307475017274 0ustar www-datawww-datamodule Tins module AskAndSend def ask_and_send(method_name, *args, &block) if respond_to?(method_name) __send__(method_name, *args, &block) end end def ask_and_send!(method_name, *args, &block) if respond_to?(method_name, true) __send__(method_name, *args, &block) end end def ask_and_send_or_self(method_name, *args, &block) if respond_to?(method_name) __send__(method_name, *args, &block) else self end end def ask_and_send_or_self!(method_name, *args, &block) if respond_to?(method_name, true) __send__(method_name, *args, &block) else self end end end end tins-1.32.1/lib/tins/named_set.rb0000644000004100000410000000022714353307475016626 0ustar www-datawww-datarequire 'set' module Tins class NamedSet < Set def initialize(name) @name = name super() end attr_accessor :name end end tins-1.32.1/lib/tins/deep_dup.rb0000644000004100000410000000024414353307475016453 0ustar www-datawww-datamodule Tins module DeepDup def deep_dup Marshal.load(Marshal.dump(self)) rescue TypeError return self end end end require 'tins/alias' tins-1.32.1/lib/tins/dslkit.rb0000644000004100000410000004436514353307475016174 0ustar www-datawww-datarequire 'thread' require 'sync' require 'tins/thread_local' module Tins # This module contains some handy methods to deal with eigenclasses. Those # are also known as virtual classes, singleton classes, metaclasses, plus all # the other names Matz doesn't like enough to actually accept one of the # names. # # The module can be included into other modules/classes to make the methods available. module Eigenclass # Returns the eigenclass of this object. def eigenclass end alias eigenclass singleton_class # Evaluates the _block_ in context of the eigenclass of this object. def eigenclass_eval(&block) eigenclass.instance_eval(&block) end end module ClassMethod include Eigenclass # Define a class method named _name_ using _block_. def class_define_method(name, &block) eigenclass_eval { define_method(name, &block) } end # Define reader and writer attribute methods for all *ids. def class_attr_accessor(*ids) eigenclass_eval { attr_accessor(*ids) } end # Define reader attribute methods for all *ids. def class_attr_reader(*ids) eigenclass_eval { attr_reader(*ids) } end # Define writer attribute methods for all *ids. def class_attr_writer(*ids) eigenclass_eval { attr_writer(*ids) } end # I boycott attr! end module ThreadGlobal # Define a thread global variable named _name_ in this module/class. If the # value _value_ is given, it is used to initialize the variable. def thread_global(name, default_value = nil, &default) is_a?(Module) or raise TypeError, "receiver has to be a Module" default_value && default and raise ArgumentError, "require either default_falue or default block" if default_value default = -> * { default_value } end name = name.to_s var_name = "@__#{name}_#{__id__.abs}__" lock = Mutex.new modul = self define_method(name) do lock.synchronize { if default && !modul.instance_variable_defined?(var_name) modul.instance_variable_set var_name, default.call end modul.instance_variable_get var_name } end define_method(name + "=") do |value| lock.synchronize { modul.instance_variable_set var_name, value } end self end # Define a thread global variable for the current instance with name # _name_. If the value _value_ is given, it is used to initialize the # variable. def instance_thread_global(name, value = nil) sc = class << self extend Tins::ThreadGlobal self end sc.thread_global name, value self end end module InstanceExec def self.included(*) super warn "#{self} is deprecated, but included at #{caller.first[/(.*):/, 1]}" end end module Interpreter # Interpret the string _source_ as a body of a block, while passing # *args into the block. # # A small example explains how the method is supposed to be used and how # the *args can be fetched: # # class A # include Tins::Interpreter # def c # 3 # end # end # # A.new.interpret('|a,b| a + b + c', 1, 2) # => 6 # # To use a specified binding see #interpret_with_binding. def interpret(source, *args) interpret_with_binding(source, binding, *args) end # Interpret the string _source_ as a body of a block, while passing # *args into the block and using _my_binding_ for evaluation. # # A small example: # # class A # include Tins::Interpreter # def c # 3 # end # def foo # b = 2 # interpret_with_binding('|a| a + b + c', binding, 1) # => 6 # end # end # A.new.foo # => 6 # # See also #interpret. def interpret_with_binding(source, my_binding, *args) path = '(interpret)' if source.respond_to? :to_io path = source.path if source.respond_to? :path source = source.to_io.read end block = lambda { |*a| eval("lambda { #{source} }", my_binding, path).call(*a) } instance_exec(*args, &block) end end # This module contains the _constant_ method. For small example of its usage # see the documentation of the DSLAccessor module. module Constant # Create a constant named _name_, that refers to value _value_. _value is # frozen, if this is possible. If you want to modify/exchange a value use # DSLAccessor#dsl_reader/DSLAccessor#dsl_accessor instead. def constant(name, value = name) value = value.freeze rescue value define_method(name) { value } end end # The DSLAccessor module contains some methods, that can be used to make # simple accessors for a DSL. # # # class CoffeeMaker # extend Tins::Constant # # constant :on # constant :off # # extend Tins::DSLAccessor # # dsl_accessor(:state) { off } # Note: the off constant from above is used # # dsl_accessor :allowed_states, :on, :off # # def process # allowed_states.include?(state) or fail "Explode!!!" # if state == on # puts "Make coffee." # else # puts "Idle..." # end # end # end # # cm = CoffeeMaker.new # cm.instance_eval do # state # => :off # state on # state # => :on # process # => outputs "Make coffee." # end # # Note that Tins::SymbolMaker is an alternative for Tins::Constant in # this example. On the other hand SymbolMaker can make debugging more # difficult. module DSLAccessor # This method creates a dsl accessor named _name_. If nothing else is given # as argument it defaults to nil. If *default is given as a single # value it is used as a default value, if more than one value is given the # _default_ array is used as the default value. If no default value but a # block _block_ is given as an argument, the block is executed everytime # the accessor is read in the context of the current instance. # # After setting up the accessor, the set or default value can be retrieved # by calling the method +name+. To set a value one can call name # :foo to set the attribute value to :foo or # name(:foo, :bar) to set it to [ :foo, :bar ]. def dsl_accessor(name, *default, &block) variable = "@#{name}" define_method(name) do |*args| if args.empty? result = if instance_variable_defined?(variable) instance_variable_get(variable) end if result.nil? result = if default.empty? block && instance_eval(&block) elsif default.size == 1 default.first else default end instance_variable_set(variable, result) result else result end else instance_variable_set(variable, args.size == 1 ? args.first : args) end end end # This method creates a dsl reader accessor, that behaves exactly like a # #dsl_accessor but can only be read not set. def dsl_reader(name, *default, &block) variable = "@#{name}" define_method(name) do |*args| if args.empty? result = if instance_variable_defined?(variable) instance_variable_get(variable) end if result.nil? if default.empty? block && instance_eval(&block) elsif default.size == 1 default.first else default end else result end else raise ArgumentError, "wrong number of arguments (#{args.size} for 0)" end end end end # This module can be included in another module/class. It generates a symbol # for every missing method that was called in the context of this # module/class. module SymbolMaker # Returns a symbol (_id_) for every missing method named _id_. def method_missing(id, *args) if args.empty? id else super end end end # This module can be used to extend another module/class. It generates # symbols for every missing constant under the namespace of this # module/class. module ConstantMaker # Returns a symbol (_id_) for every missing constant named _id_. def const_missing(id) id end end module BlankSlate # Creates an anonymous blank slate class, that only responds to the methods # *ids. ids can be Symbols, Strings, and Regexps that have to match # the method name with #===. def self.with(*ids) opts = Hash === ids.last ? ids.pop : {} ids = ids.map { |id| Regexp === id ? id : id.to_s } klass = opts[:superclass] ? Class.new(opts[:superclass]) : Class.new klass.instance_eval do instance_methods.each do |m| m = m.to_s undef_method m unless m =~ /^(__|object_id)/ or ids.any? { |i| i === m } end end klass end end # See examples/recipe.rb and examples/recipe2.rb how this works at the # moment. module Deflect # The basic Deflect exception class DeflectError < StandardError; end class << self extend Tins::ThreadLocal # A thread local variable, that holds a DeflectorCollection instance for # the current thread. thread_local :deflecting end # A deflector is called with a _class_, a method _id_, and its # *args. class Deflector < Proc; end # This class implements a collection of deflectors, to make them available # by emulating Ruby's message dispatch. class DeflectorCollection def initialize @classes = {} end # Add a new deflector _deflector_ for class _klass_ and method name _id_, # and return self. # def add(klass, id, deflector) k = @classes[klass] k = @classes[klass] = {} unless k k[id.to_s] = deflector self end # Return true if messages are deflected for class _klass_ and method name # _id_, otherwise return false. def member?(klass, id) !!(k = @classes[klass] and k.key?(id.to_s)) end # Delete the deflecotor class _klass_ and method name _id_. Returns the # deflector if any was found, otherwise returns true. def delete(klass, id) if k = @classes[klass] d = k.delete id.to_s @classes.delete klass if k.empty? d end end # Try to find a deflector for class _klass_ and method _id_ and return # it. If none was found, return nil instead. def find(klass, id) klass.ancestors.find do |k| if d = @classes[k] and d = d[id.to_s] return d end end end end @@sync = Sync.new # Start deflecting method calls named _id_ to the _from_ class using the # Deflector instance deflector. def deflect_start(from, id, deflector) @@sync.synchronize do Deflect.deflecting ||= DeflectorCollection.new Deflect.deflecting.member?(from, id) and raise DeflectError, "#{from}##{id} is already deflected" Deflect.deflecting.add(from, id, deflector) from.class_eval do define_method(id) do |*args| if Deflect.deflecting and d = Deflect.deflecting.find(self.class, id) d.call(self, id, *args) else super(*args) end end end end end # Return true if method _id_ is deflected from class _from_, otherwise # return false. def self.deflect?(from, id) Deflect.deflecting && Deflect.deflecting.member?(from, id) end # Return true if method _id_ is deflected from class _from_, otherwise # return false. def deflect?(from, id) Deflect.deflect?(from, id) end # Start deflecting method calls named _id_ to the _from_ class using the # Deflector instance deflector. After that yield to the given block and # stop deflecting again. def deflect(from, id, deflector) @@sync.synchronize do begin deflect_start(from, id, deflector) yield ensure deflect_stop(from, id) end end end # Stop deflection method calls named _id_ to class _from_. def deflect_stop(from, id) @@sync.synchronize do Deflect.deflecting.delete(from, id) or raise DeflectError, "#{from}##{id} is not deflected from" from.instance_eval { remove_method id } end end end # This module can be included into modules/classes to make the delegate # method available. module Delegate UNSET = Object.new # A method to easily delegate methods to an object, stored in an # instance variable or returned by a method call. # # It's used like this: # class A # delegate :method_here, :@obj, :method_there # end # or: # class A # delegate :method_here, :method_call, :method_there # end # # _other_method_name_ defaults to method_name, if it wasn't given. #def delegate(method_name, to: UNSET, as: method_name) def delegate(method_name, opts = {}) to = opts[:to] || UNSET as = opts[:as] || method_name raise ArgumentError, "to argument wasn't defined" if to == UNSET to = to.to_s case when to[0, 2] == '@@' define_method(as) do |*args, &block| if self.class.class_variable_defined?(to) self.class.class_variable_get(to).__send__(method_name, *args, &block) end end when to[0] == ?@ define_method(as) do |*args, &block| if instance_variable_defined?(to) instance_variable_get(to).__send__(method_name, *args, &block) end end when (?A..?Z).include?(to[0]) define_method(as) do |*args, &block| Tins::DeepConstGet.deep_const_get(to).__send__(method_name, *args, &block) end else define_method(as) do |*args, &block| __send__(to).__send__(method_name, *args, &block) end end end end # This module includes the block_self module_function. module BlockSelf module_function # This method returns the receiver _self_ of the context in which _block_ # was created. def block_self(&block) eval 'self', block.__send__(:binding) end end # This module contains a configurable method missing delegator and can be # mixed into a module/class. module MethodMissingDelegator # Including this module in your classes makes an _initialize_ method # available, whose first argument is used as method_missing_delegator # attribute. If a superior _initialize_ method was defined it is called # with all arguments but the first. module DelegatorModule include Tins::MethodMissingDelegator def initialize(delegator, *a, &b) self.method_missing_delegator = delegator super(*a, &b) if defined? super end end # This class includes DelegatorModule and can be used as a superclass # instead of including DelegatorModule. class DelegatorClass include DelegatorModule end # This object will be the receiver of all missing method calls, if it has a # value other than nil. attr_accessor :method_missing_delegator # Delegates all missing method calls to _method_missing_delegator_ if this # attribute has been set. Otherwise it will call super. def method_missing(id, *a, &b) unless method_missing_delegator.nil? method_missing_delegator.__send__(id, *a, &b) else super end end end module ParameterizedModule # Pass _args_ and _block_ to configure the module and then return it after # calling the parameterize method has been called with these arguments. The # _parameterize_ method should return a configured module. def parameterize_for(*args, &block) respond_to?(:parameterize) ? parameterize(*args, &block) : self end end module FromModule include ParameterizedModule alias from parameterize_for def parameterize(opts = {}) modul = opts[:module] or raise ArgumentError, 'option :module is required' import_methods = Array(opts[:methods]) result = modul.dup remove_methods = modul.instance_methods.map(&:to_sym) - import_methods.map(&:to_sym) remove_methods.each do |m| begin result.__send__ :remove_method, m rescue NameError end end result end end module Scope def scope_push(scope_frame, name = :default) scope_get(name).push scope_frame self end def scope_pop(name = :default) scope_get(name).pop scope_get(name).empty? and Thread.current[name] = nil self end def scope_top(name = :default) scope_get(name).last end def scope_reverse(name = :default, &block) scope_get(name).reverse_each(&block) end def scope_block(scope_frame, name = :default) scope_push(scope_frame, name) yield ensure scope_pop(name) end def scope_get(name = :default) Thread.current[name] ||= [] end def scope(name = :default) scope_get(name).dup end end module DynamicScope class Context < Hash def [](name) super name.to_sym end def []=(name, value) super name.to_sym, value end end include Scope attr_accessor :dynamic_scope_name def dynamic_defined?(id) self.dynamic_scope_name ||= :variables scope_reverse(dynamic_scope_name) { |c| c.key?(id) and return true } false end def dynamic_scope(&block) self.dynamic_scope_name ||= :variables scope_block(Context.new, dynamic_scope_name, &block) end def method_missing(id, *args) self.dynamic_scope_name ||= :variables if args.empty? and scope_reverse(dynamic_scope_name) { |c| c.key?(id) and return c[id] } super elsif args.size == 1 and id.to_s =~ /(.*?)=\Z/ c = scope_top(dynamic_scope_name) or super c[$1] = args.first else super end end end end DSLKit = Tins tins-1.32.1/lib/tins/module_group.rb0000644000004100000410000000032414353307475017366 0ustar www-datawww-datamodule Tins module ModuleGroup def self.[](*modules) modul = Module.new modules.each do |m| m.module_eval { include modul } end modul end end end require 'tins/alias' tins-1.32.1/lib/tins/file_binary.rb0000644000004100000410000000513114353307475017151 0ustar www-datawww-datamodule Tins module FileBinary module Constants SEEK_SET = ::File::SEEK_SET ZERO = "\x00" BINARY = "\x01-\x1f\x7f-\xff" if defined?(::Encoding) ZERO.force_encoding(Encoding::ASCII_8BIT) BINARY.force_encoding(Encoding::ASCII_8BIT) end end class << self # Default options can be queried/set via this hash. attr_accessor :default_options end self.default_options = { offset: 0, buffer_size: 2 ** 13, percentage_binary: 30.0, percentage_zeros: 0.0, } # Returns true if this file is considered to be binary, false if it is not # considered to be binary, and nil if it was empty. # # A file is considered to be binary if the percentage of zeros exceeds # options[:percentage_zeros] or the percentage of binary bytes # (8-th bit is 1) exceeds options[:percentage_binary] in the # buffer of size options[:buffer_size] that is checked (beginning # from offset options[:offset]). If an option isn't given the one # from FileBinary.default_options is used instead. def binary?(options = {}) options = FileBinary.default_options.merge(options) old_pos = tell seek options[:offset], Constants::SEEK_SET data = read options[:buffer_size] !data or data.empty? and return nil data_size = data.size data.count(Constants::ZERO).to_f / data_size > options[:percentage_zeros] / 100.0 and return true data.count(Constants::BINARY).to_f / data_size > options[:percentage_binary] / 100.0 ensure old_pos and seek old_pos, Constants::SEEK_SET end # Returns true if FileBinary#binary? returns false, false if # FileBinary#binary? returns true, and nil otherwise. For an explanation of # +options+, see FileBinary#binary?. def ascii?(options = {}) case binary?(options) when true then false when false then true end end def self.included(modul) modul.instance_eval do extend ClassMethods end super end module ClassMethods # Returns true if the file with name +name+ is considered to be binary # using the FileBinary#binary? method. def binary?(name, options = {}) open(name, 'rb') { |f| f.binary?(options) } end # Returns true if the file with name +name+ is considered to be ascii # using the FileBinary#ascii? method. def ascii?(name, options = {}) open(name, 'rb') { |f| f.ascii?(options) } end end end end require 'tins/alias' tins-1.32.1/lib/tins/p.rb0000644000004100000410000000116314353307475015126 0ustar www-datawww-datarequire 'pp' module Tins module P private # Raise a runtime error with the inspected objects +objs+ (obtained by # calling the #inspect method) as their message text. This is useful for # quick debugging. def p!(*objs) raise((objs.size < 2 ? objs.first : objs).inspect) end # Raise a runtime error with the inspected objects +objs+ (obtained by # calling the #pretty_inspect method) as their message text. This is useful # for quick debugging. def pp!(*objs) raise("\n" + (objs.size < 2 ? objs.first : objs).pretty_inspect.chomp) end end end require 'tins/alias' tins-1.32.1/lib/tins/null.rb0000644000004100000410000000250514353307475015642 0ustar www-datawww-datamodule Tins # Implementation of the null object pattern in Ruby. module Null def method_missing(*) self end def const_missing(*) self end def to_s '' end def to_str nil end def to_f 0.0 end def to_i 0 end def to_int nil end def to_a [] end def to_ary nil end def inspect 'NULL' end def nil? true end def blank? true end def as_json(*) end def to_json(*) 'null' end module Kernel def null(value = nil) value.nil? ? Tins::NULL : value end alias Null null def null_plus(opts = {}) value = opts[:value] opts[:caller] = caller if respond_to?(:caller_locations, true) opts[:caller_locations] = caller_locations end value.nil? ? Tins::NullPlus.new(opts) : value end alias NullPlus null_plus end end class NullClass < Module include Tins::Null end NULL = NullClass.new NULL.freeze class NullPlus include Tins::Null def initialize(opts = {}) singleton_class.class_eval do opts.each do |name, value| define_method(name) { value } end end end end end require 'tins/alias' tins-1.32.1/lib/tins/case_predicate.rb0000644000004100000410000000015514353307475017622 0ustar www-datawww-datamodule Tins module CasePredicate def case?(*args) args.find { |a| a === self } end end end tins-1.32.1/lib/tins/attempt.rb0000644000004100000410000000722014353307475016345 0ustar www-datawww-datamodule Tins module Attempt # Attempts code in block *attempts* times, sleeping according to *sleep* # between attempts and catching the exception(s) in *exception_class*. # # *sleep* is either a Proc returning a floating point number for duration # as seconds or a Numeric >= 0 or < 0. In the former case this is the # duration directly, in the latter case -*sleep* is the total number of # seconds that is slept before giving up, and every attempt is retried # after a exponentially increasing duration of seconds. # # Iff *reraise* is true the caught exception is reraised after running out # of attempts. def attempt(opts = {}, &block) sleep = nil exception_class = StandardError prev_exception = nil if Numeric === opts attempts = opts else attempts = opts[:attempts] || 1 attempts >= 1 or raise ArgumentError, 'at least one attempt is required' exception_class = opts[:exception_class] if opts.key?(:exception_class) sleep = interpret_sleep(opts[:sleep], attempts) reraise = opts[:reraise] end return if attempts <= 0 count = 0 if exception_class.nil? begin count += 1 if block.call(count, prev_exception) return true elsif count < attempts sleep_duration(sleep, count) end end until count == attempts false else begin count += 1 block.call(count, prev_exception) true rescue *exception_class if count < attempts prev_exception = $! sleep_duration(sleep, count) retry end case reraise when Proc reraise.($!) when Exception.class raise reraise, "reraised: #{$!.message}" when true raise $!, "reraised: #{$!.message}" else false end end end end private def sleep_duration(duration, count) case duration when Numeric sleep duration when Proc sleep duration.call(count) end end def compute_duration_base(sleep, attempts) x1, x2 = 1, sleep attempts <= sleep or raise ArgumentError, "need less or equal number of attempts than sleep duration #{sleep}" x1 >= x2 and raise ArgumentError, "invalid sleep argument: #{sleep.inspect}" function = -> x { (0...attempts).inject { |s, i| s + x ** i } - sleep } f, fmid = function[x1], function[x2] f * fmid >= 0 and raise ArgumentError, "invalid sleep argument: #{sleep.inspect}" n = 1 << 16 epsilon = 1E-16 root = if f < 0 dx = x2 - x1 x1 else dx = x1 - x2 x2 end n.times do fmid = function[xmid = root + (dx *= 0.5)] fmid < 0 and root = xmid dx.abs < epsilon or fmid == 0 and return root end raise ArgumentError, "too many iterations (#{n})" result end def interpret_sleep(sleep, attempts) case sleep when nil when Numeric if sleep < 0 if attempts > 2 sleep = -sleep duration_base = compute_duration_base sleep, attempts sleep = lambda { |i| duration_base ** i } else raise ArgumentError, "require > 2 attempts for negative sleep value" end end sleep when Proc sleep else raise TypeError, "require Proc or Numeric sleep argument" end end end end tins-1.32.1/lib/tins/xt.rb0000644000004100000410000000244014353307475015321 0ustar www-datawww-datarequire 'tins' module Tins require 'tins/xt/attempt' require 'tins/xt/blank' require 'tins/xt/count_by' require 'tins/xt/deep_dup' require 'tins/xt/file_binary' require 'tins/xt/full' require 'tins/xt/hash_symbolize_keys_recursive' require 'tins/xt/hash_union' require 'tins/xt/irb' require 'tins/xt/named' require 'tins/xt/null' require 'tins/xt/p' require 'tins/xt/partial_application' require 'tins/xt/range_plus' require 'tins/xt/require_maybe' require 'tins/xt/secure_write' require 'tins/xt/string' require 'tins/xt/subhash' require 'tins/xt/time_dummy' require 'tins/xt/date_dummy' require 'tins/xt/date_time_dummy' require 'tins/xt/uniq_by' require 'tins/xt/write' require 'tins/xt/if_predicate' require 'tins/xt/ask_and_send' require 'tins/xt/extract_last_argument_options' require 'tins/xt/deep_const_get' require 'tins/xt/responding' require 'tins/xt/proc_compose' require 'tins/xt/proc_prelude' require 'tins/xt/sexy_singleton' require 'tins/xt/method_description' require 'tins/xt/annotate' require 'tins/xt/concern' require 'tins/xt/dslkit' require 'tins/xt/time_freezer' require 'tins/xt/case_predicate' require 'tins/xt/implement' require 'tins/xt/complete' require 'tins/xt/expose' require 'tins/xt/temp_io' end tins-1.32.1/lib/tins/count_by.rb0000644000004100000410000000022114353307475016503 0ustar www-datawww-datamodule Tins module CountBy def count_by(&b) b ||= lambda { |x| true } inject(0) { |s, e| s += 1 if b[e]; s } end end end tins-1.32.1/lib/tins/limited.rb0000644000004100000410000000201114353307475016307 0ustar www-datawww-datarequire 'thread' module Tins class Limited # Create a Limited instance, that runs _maximum_ threads at most. def initialize(maximum) @mutex = Mutex.new @continue = ConditionVariable.new @maximum = Integer(maximum) raise ArgumentError, "maximum < 1" if @maximum < 1 @count = 0 @tg = ThreadGroup.new end # The maximum number of worker threads. attr_reader :maximum # Execute _maximum_ number of threads in parallel. def execute @mutex.synchronize do loop do if @count < @maximum @count += 1 Thread.new do @tg.add Thread.current yield @mutex.synchronize { @count -= 1 } @continue.signal end return else @continue.wait(@mutex) end end end end def wait @tg.list.each(&:join) end def process yield self ensure wait end end end require 'tins/alias' tins-1.32.1/lib/tins/subhash.rb0000644000004100000410000000241314353307475016323 0ustar www-datawww-datamodule Tins module Subhash # Create a subhash from this hash, that only contains key-value pairs # matching +patterns+ and return it. +patterns+ can be for example /^foo/ # to put 'foobar' and 'foobaz' or 'foo'/:foo to put 'foo' into the subhash. # # If a block is given this method yields to it after the first pattern # matched with a 3-tuple of +(key, value, match_data)+ using the return # value of the block as the value of the result hash. +match_data+ is a # MatchData instance if the matching pattern was a regular rexpression # otherwise it is nil. def subhash(*patterns) patterns.map! do |pat| pat = pat.to_sym.to_s if pat.respond_to?(:to_sym) pat.respond_to?(:match) ? pat : pat.to_s end result = if default_proc self.class.new(&default_proc) else self.class.new(default) end if block_given? each do |k, v| patterns.each { |pat| if pat === k.to_s result[k] = yield(k, v, $~) break end } end else each do |k, v| result[k] = v if patterns.any? { |pat| pat === k.to_s } end end result end end end require 'tins/alias' tins-1.32.1/lib/tins/responding.rb0000644000004100000410000000061314353307475017036 0ustar www-datawww-datamodule Tins module Responding def responding?(*method_names) Class.new do define_method(:to_s) do "Responding to #{method_names * ', '}" end alias inspect to_s define_method(:===) do |object| method_names.all? do |method_name| object.respond_to?(method_name) end end end.new end end end tins-1.32.1/lib/tins/memoize.rb0000644000004100000410000000612514353307475016337 0ustar www-datawww-datarequire 'tins/extract_last_argument_options' module Tins module Memoize module CacheMethods # Return the cache object. def __memoize_cache__ @__memoize_cache__ ||= {} end # Clear cached values for all methods/functions. def memoize_cache_clear __memoize_cache__.clear self end def memoize_apply_visibility(id) visibility = instance_eval do case when private_method_defined?(id) :private when protected_method_defined?(id) :protected end end yield ensure visibility and __send__(visibility, id) end end class ::Module # Automatically memoize calls of the the methods +method_ids+. The # memoized results do NOT ONLY depend on the arguments, but ALSO on the # object the method is called on. def memoize_method(*method_ids) method_ids.extend(ExtractLastArgumentOptions) method_ids, opts = method_ids.extract_last_argument_options include CacheMethods method_ids.each do |method_id| method_id = method_id.to_s.to_sym memoize_apply_visibility method_id do orig_method = instance_method(method_id) __send__(:define_method, method_id) do |*args| mc = __memoize_cache__ if mc.key?(method_id) and result = mc[method_id][args] result else (mc[method_id] ||= {})[args] = result = orig_method.bind(self).call(*args) $DEBUG and warn "#{self.class} cached method #{method_id}(#{args.inspect unless args.empty?}) = #{result.inspect} [#{__id__}]" opts[:freeze] and result.freeze end result end end end method_ids.size == 1 ? method_ids.first : method_ids end include CacheMethods # Automatically memoize calls of the functions +function_ids+. The # memoized result does ONLY depend on the arguments given to the # function. def memoize_function(*function_ids) function_ids.extend(ExtractLastArgumentOptions) function_ids, opts = function_ids.extract_last_argument_options mc = __memoize_cache__ function_ids.each do |function_id| function_id = function_id.to_s.to_sym memoize_apply_visibility function_id do orig_function = instance_method(function_id) __send__(:define_method, function_id) do |*args| if mc.key?(function_id) and result = mc[function_id][args] result else (mc[function_id] ||= {})[args] = result = orig_function.bind(self).call(*args) opts[:freeze] and result.freeze $DEBUG and warn "#{self.class} cached function #{function_id}(#{args.inspect unless args.empty?}) = #{result.inspect}" end result end end end function_ids.size == 1 ? function_ids.first : function_ids end end end end require 'tins/alias' tins-1.32.1/lib/tins/annotate.rb0000644000004100000410000000233514353307475016502 0ustar www-datawww-datamodule Tins::Annotate def annotate(name) singleton_class.class_eval do define_method(name) do |annotation = :annotated| instance_variable_set "@__annotation_#{name}__", annotation end define_method("#{name}_of") do |method_name| __send__("#{name}_annotations")[method_name] end define_method("#{name}_annotations") do if instance_variable_defined?("@__annotation_#{name}_annotations__") instance_variable_get "@__annotation_#{name}_annotations__" else instance_variable_set "@__annotation_#{name}_annotations__", {} end end old_method_added = instance_method(:method_added) define_method(:method_added) do |method_name| old_method_added.bind(self).call method_name if annotation = instance_variable_get("@__annotation_#{name}__") __send__("#{name}_annotations")[method_name] = annotation end instance_variable_set "@__annotation_#{name}__", nil end end define_method("#{name}_annotations") do self.class.__send__("#{name}_annotations") end define_method("#{name}_of") do |method_name| self.class.__send__("#{name}_of", method_name) end end end tins-1.32.1/lib/tins/string_underscore.rb0000644000004100000410000000044514353307475020430 0ustar www-datawww-datamodule Tins module StringUnderscore def underscore word = dup word.gsub!(/::/, '/') word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2') word.gsub!(/([a-z\d])([A-Z])/,'\1_\2') word.tr!("-", "_") word.downcase! word end end end require 'tins/alias' tins-1.32.1/lib/tins/deep_const_get.rb0000644000004100000410000000267514353307475017662 0ustar www-datawww-datamodule Tins module DeepConstGet if ::Object.method(:const_defined?).arity == 1 # :nocov: # We do not create coverage on 1.8 def self.const_defined_in?(modul, constant) modul.const_defined?(constant) end # :nocov: else def self.const_defined_in?(modul, constant) modul.const_defined?(constant, false) end end if Tins::StringVersion(RUBY_VERSION) < Tins::StringVersion('2.0') def self.deep_const_get(path, start_module = Object) path.to_s.split('::').inject(start_module) do |p, c| case when c.empty? if start_module == Object Object else raise ArgumentError, "top level constants cannot be reached from"\ " start module #{start_module.inspect}" end when const_defined_in?(p, c) p.const_get(c) else begin p.const_missing(c) rescue NameError => e raise ArgumentError, "can't get const #{path}: #{e}" end end end end else def self.deep_const_get(path, start_module = Object) start_module.const_get(path) rescue NameError => e raise ArgumentError, "can't get const #{path}: #{e}" end end def deep_const_get(path, start_module = Object) ::Tins::DeepConstGet.deep_const_get(path, start_module) end end end tins-1.32.1/lib/tins/minimize.rb0000644000004100000410000000336214353307475016513 0ustar www-datawww-datamodule Tins # This module can be mixed into all classes, whose instances respond to the # [] and size-methods, like for example Array. The returned elements from [] # should respond to the succ method. module Minimize # Returns a minimized version of this object, that is successive elements # are substituted with ranges a..b. In the situation ..., x, y,... and y != # x.succ a range x..x is created, to make it easier to iterate over all the # ranges in one run. A small example: # [ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ].minimize # => [ 'A'..'C', 'G'..'G', 'K'..'M' ] # # If the order of the original elements doesn't matter, it's a good idea to # first sort them and then minimize: # [ 5, 1, 4, 2 ].sort.minimize # => [ 1..2, 4..5 ] def minimize result = [] last_index = size - 1 size.times do |i| result << [ self[0] ] if i == 0 if self[i].succ != self[i + 1] or i == last_index result[-1] << self[i] result << [ self[i + 1] ] unless i == last_index end end result.map! { |a, b| a..b } end # First minimizes this object, then calls the replace method with the # result. def minimize! replace minimize end # Invert a minimized version of an object. Some small examples: # [ 'A'..'C', 'G'..'G', 'K'..'M' ].unminimize # => [ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ] # and # [ 1..2, 4..5 ].unminimize # => [ 1, 2, 4, 5 ] def unminimize result = [] for range in self for e in range result << e end end result end # Invert a minimized version of this object in place. def unminimize! replace unminimize end end end require 'tins/alias' tins-1.32.1/lib/tins/expose.rb0000644000004100000410000000155614353307475016200 0ustar www-datawww-datamodule Tins module Expose # Expose any (private/protected) method or internal state of this object # returning the result for specing purposes. # # @param method_name [ Symbol | String ] name of the method # (shortcut for reader methods). # @param block [ Proc ] any private/protected methods of the object can be # called in this block. # # @return [ Object ] result of the method or block call def expose(method_name = nil, *args, &block) if block instance_eval(&block) elsif method_name.nil? methods = private_methods(true) + protected_methods(true) o = dup o.singleton_class.class_eval do public(*methods) end o elsif method_name __send__(method_name, *args) end end end end tins-1.32.1/lib/tins/uniq_by.rb0000644000004100000410000000025114353307475016332 0ustar www-datawww-datamodule Tins module UniqBy def uniq_by(&b) b ||= lambda { |x| x } inject({}) { |h, e| h[b[e]] ||= e; h }.values end end end require 'tins/alias' tins-1.32.1/lib/tins/token.rb0000644000004100000410000000231714353307475016011 0ustar www-datawww-datarequire 'securerandom' module Tins class Token < String DEFAULT_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".freeze BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".freeze BASE64_URL_FILENAME_SAFE_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".freeze BASE32_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".freeze BASE32_EXTENDED_HEX_ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUV".freeze BASE16_ALPHABET = "0123456789ABCDEF".freeze def initialize(bits: 128, length: nil, alphabet: DEFAULT_ALPHABET, random: SecureRandom) alphabet.size > 1 or raise ArgumentError, 'need at least 2 symbols in alphabet' if length length > 0 or raise ArgumentError, 'length has to be positive' else bits > 0 or raise ArgumentError, 'bits has to be positive' length = (Math.log(1 << bits) / Math.log(alphabet.size)).ceil end self.bits = (Math.log(alphabet.size ** length) / Math.log(2)).floor token = '' length.times { token << alphabet[random.random_number(alphabet.size)] } super token end attr_accessor :bits end end tins-1.32.1/lib/tins/proc_prelude.rb0000644000004100000410000000306614353307475017356 0ustar www-datawww-datarequire 'tins/memoize' module Tins module ProcPrelude def apply(&my_proc) my_proc or raise ArgumentError, 'a block argument is required' lambda { |list| my_proc.call(*list) } end def map_apply(my_method, *args, &my_proc) my_proc or raise ArgumentError, 'a block argument is required' lambda { |x, y| my_proc.call(x, y.__send__(my_method, *args)) } end def call(obj, &my_proc) my_proc or raise ArgumentError, 'a block argument is required' obj.instance_eval(&my_proc) end def array lambda { |*list| list } end memoize_function :array, freeze: true def first lambda { |*list| list.first } end memoize_function :first, freeze: true alias head first def second lambda { |*list| list[1] } end memoize_function :second, freeze: true def tail lambda { |*list| list[1..-1] } end memoize_function :tail, freeze: true def last lambda { |*list| list.last } end memoize_function :last, freeze: true def rotate(n = 1) lambda { |*list| list.rotate(n) } end alias swap rotate def id1 lambda { |obj| obj } end memoize_function :id1, freeze: true def const(konst = nil, &my_proc) konst ||= my_proc.call lambda { |*_| konst } end def nth(n) lambda { |*list| list[n] } end def from(&block) my_method, binding = block.call, block.binding my_self = eval 'self', binding lambda { |*list| my_self.__send__(my_method, *list) } end end end tins-1.32.1/lib/tins/string_camelize.rb0000644000004100000410000000054114353307475020045 0ustar www-datawww-datamodule Tins module StringCamelize def camelize(first_letter = :upper) case first_letter when :upper, true gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } when :lower, false self[0].chr.downcase + camelize[1..-1] end end alias camelcase camelize end end require 'tins/alias' tins-1.32.1/lib/tins/require_maybe.rb0000644000004100000410000000024214353307475017515 0ustar www-datawww-datamodule Tins module RequireMaybe def require_maybe(library) require library rescue LoadError => e block_given? and yield e end end end tins-1.32.1/lib/tins/find.rb0000644000004100000410000000754414353307475015620 0ustar www-datawww-datarequire 'enumerator' require 'pathname' require 'tins/module_group' module Tins module Find EXPECTED_STANDARD_ERRORS = ModuleGroup[ Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG ] class Finder module PathExtension attr_accessor :finder def finder_stat finder.protect_from_errors do finder.follow_symlinks ? File.stat(self) : File.lstat(self) end end def file finder.protect_from_errors do File.new(self) if file? end end def file? finder.protect_from_errors { s = finder_stat and s.file? } end def directory? finder.protect_from_errors { s = finder_stat and s.directory? } end def exist? finder.protect_from_errors { File.exist?(self) } end def stat finder.protect_from_errors { File.stat(self) } end def lstat finder.protect_from_errors { File.lstat(self) } end def pathname Pathname.new(self) end def suffix pathname.extname[1..-1] || '' end end def initialize(opts = {}) @show_hidden = opts.fetch(:show_hidden) { true } @raise_errors = opts.fetch(:raise_errors) { false } @follow_symlinks = opts.fetch(:follow_symlinks) { true } if opts.key?(:visit) && opts.key?(:suffix) raise ArgumentError, 'either use visit or suffix argument' elsif opts.key?(:visit) @visit = opts.fetch(:visit) { -> path { true } } elsif opts.key?(:suffix) @suffix = Array(opts[:suffix]) @visit = -> path { @suffix.nil? || @suffix.empty? || @suffix.include?(path.suffix) } end end attr_accessor :show_hidden attr_accessor :raise_errors attr_accessor :follow_symlinks attr_accessor :suffix def visit_path?(path) if !defined?(@visit) || @visit.nil? true else @visit.(path) end end def find(*paths) block_given? or return enum_for(__method__, *paths) paths.collect! { |d| d.dup } while path = paths.shift path = prepare_path(path) catch(:prune) do stat = path.finder_stat or next visit_path?(path) and yield path if stat.directory? ps = protect_from_errors { Dir.entries(path) } or next ps.sort! ps.reverse_each do |p| next if p == "." or p == ".." next if !@show_hidden && p.start_with?('.') p = File.join(path, p) paths.unshift p end end end end end def prepare_path(path) path = path.dup path.extend PathExtension path.finder = self path end def protect_from_errors(errors = Find::EXPECTED_STANDARD_ERRORS) yield rescue errors raise_errors and raise return end end # # Calls the associated block with the name of every path and directory # listed as arguments, then recursively on their subdirectories, and so on. # # See the +Find+ module documentation for an example. # def find(*paths, &block) # :yield: path opts = Hash === paths.last ? paths.pop : {} Finder.new(opts).find(*paths, &block) end # # Skips the current path or directory, restarting the loop with the next # entry. If the current path is a directory, that directory will not be # recursively entered. Meaningful only within the block associated with # Find::find. # # See the +Find+ module documentation for an example. # def prune throw :prune end module_function :find, :prune end end tins-1.32.1/lib/tins/implement.rb0000644000004100000410000000222414353307475016660 0ustar www-datawww-datamodule Tins module Implement MESSAGES = { default: 'method %{method_name} not implemented in module %{module}', subclass: 'method %{method_name} has to be implemented in '\ 'subclasses of %{module}', submodule: 'method %{method_name} has to be implemented in '\ 'submodules of %{module}', } def implement(method_name, msg = :default) method_name.nil? and return case msg when ::Symbol msg = MESSAGES.fetch(msg) when ::Hash return implement method_name, msg.fetch(:in) end display_method_name = method_name if m = instance_method(method_name) rescue nil m.extend Tins::MethodDescription display_method_name = m.description(style: :name) end begin msg = msg % { method_name: display_method_name, module: self } rescue KeyError end define_method(method_name) do |*| raise ::NotImplementedError, msg end end def implement_in_submodule(method_name) implement method_name, 'method %{method_name} has to be implemented in submodules of'\ ' %{module}' end end end tins-1.32.1/lib/tins/lru_cache.rb0000644000004100000410000000162014353307475016612 0ustar www-datawww-datamodule Tins class LRUCache include Enumerable class << self private my_nil = Object.new.freeze define_method(:not_exist) do my_nil end end def initialize(capacity) @capacity = capacity @data = {} end attr_reader :capacity def [](key) case value = @data.delete(key){ not_exist } when not_exist nil else @data[key] = value end end def []=(key, value) @data.delete(key) @data[key] = value if @data.size > @capacity @data.delete(@data.keys.first) end value end def each(&block) @data.reverse_each(&block) end def delete(key) @data.delete(key) end def clear @data.clear end def size @data.size end private def not_exist self.class.send(:not_exist) end end end tins-1.32.1/lib/tins/time_dummy.rb0000644000004100000410000000261114353307475017037 0ustar www-datawww-datarequire 'time' module Tins module TimeDummy def self.included(modul) class << modul alias really_new new alias really_now now remove_method :now rescue nil remove_method :new rescue nil def dummy=(value) if value.respond_to?(:to_str) value = Time.parse(value.to_str) elsif value.respond_to?(:to_time) value = value.to_time end @dummy = value end def dummy(value = nil) if value.nil? if defined?(@dummy) @dummy end else begin old_dummy = @dummy self.dummy = value yield ensure self.dummy = old_dummy end end end if RUBY_VERSION >= "3.0" def new(*a, **kw) if dummy dummy.dup elsif caller.first =~ /`now`/ really_now(**kw) else really_new(*a, **kw) end end else def new(*a) if dummy dummy.dup elsif caller.first =~ /`now`/ really_now else really_new(*a) end end end def now new end end super end end end require 'tins/alias' tins-1.32.1/lib/tins/date_dummy.rb0000644000004100000410000000176314353307475017025 0ustar www-datawww-datarequire 'date' module Tins module DateDummy def self.included(modul) class << modul alias really_today today remove_method :today rescue nil def dummy=(value) if value.respond_to?(:to_str) value = Date.parse(value.to_str) elsif value.respond_to?(:to_date) value = value.to_date end @dummy = value end def dummy(value = nil) if value.nil? if defined?(@dummy) @dummy end else begin old_dummy = @dummy self.dummy = value yield ensure self.dummy = old_dummy end end end def today if dummy dummy.dup elsif caller.first =~ /`today`/ really_today else really_today end end end super end end end require 'tins/alias' tins-1.32.1/lib/tins/proc_compose.rb0000644000004100000410000000042414353307475017356 0ustar www-datawww-datamodule Tins module ProcCompose def compose(other) self.class.new do |*args| if other.respond_to?(:call) call(*other.call(*args)) else call(*other.to_proc.call(*args)) end end end alias * compose end end tins-1.32.1/lib/tins/bijection.rb0000644000004100000410000000174314353307475016641 0ustar www-datawww-datamodule Tins class Bijection < Hash def self.[](*pairs) pairs.size % 2 == 0 or raise ArgumentError, "odd number of arguments for #{self}" new.fill do |obj| (pairs.size / 2).times do |i| j = 2 * i key = pairs[j] value = pairs[j + 1] obj.key?(key) and raise ArgumentError, "duplicate key #{key.inspect} for #{self}" obj.inverted.key?(value) and raise ArgumentError, "duplicate value #{value.inspect} for #{self}" obj[pairs[j]] = pairs[j + 1] end end end def initialize(inverted = Bijection.new(self)) @inverted = inverted end def fill if empty? yield self freeze end self end def freeze r = super unless @inverted.frozen? @inverted.freeze end r end def []=(key, value) key?(key) and return super @inverted[value] = key end attr_reader :inverted end end tins-1.32.1/lib/tins/hash_union.rb0000644000004100000410000000041114353307475017015 0ustar www-datawww-datamodule Tins module HashUnion def |(other) case when other.respond_to?(:to_hash) other = other.to_hash when other.respond_to?(:to_h) other = other.to_h end other.merge(self) end end end require 'tins/alias' tins-1.32.1/lib/tins/write.rb0000644000004100000410000000071414353307475016022 0ustar www-datawww-datarequire 'tins/secure_write' module Tins module Write def self.extended(modul) modul.extend SecureWrite if modul.respond_to?(:write) $DEBUG and warn "Skipping inclusion of Tins::Write#write method, include Tins::Write::SecureWrite#secure_write instead" else class << modul; self; end.instance_eval do alias_method :write, :secure_write end end super end end end require 'tins/alias' tins-1.32.1/lib/tins/string_byte_order_mark.rb0000644000004100000410000000131214353307475021421 0ustar www-datawww-datarequire 'tins/concern' module Tins module StringByteOrderMark def bom_encoding prefix = self[0, 4].force_encoding(Encoding::ASCII_8BIT) case prefix when /\A\xef\xbb\xbf/n then Encoding::UTF_8 when /\A\x00\x00\xff\xfe/n then Encoding::UTF_32BE when /\A\xff\xfe\x00\x00/n then Encoding::UTF_32LE when /\A\xfe\xff/n then Encoding::UTF_16BE when /\A\xff\xfe/n then Encoding::UTF_16LE when /\A\x2b\x2f\x76[\x38-\x39\x2b\x2f]/n then Encoding::UTF_7 when /\A\x84\x31\x95\x33/n then Encoding::GB18030 end end end end require 'tins/alias' tins-1.32.1/lib/tins/thread_local.rb0000644000004100000410000000275114353307475017314 0ustar www-datawww-datamodule Tins module ThreadLocal @@cleanup = lambda do |my_object_id| my_id = "__thread_local_#{my_object_id}__" for t in Thread.list t[my_id] = nil if t[my_id] end end # Define a thread local variable named _name_ in this module/class. If the # value _value_ is given, it is used to initialize the variable. def thread_local(name, default_value = nil, &default) is_a?(Module) or raise TypeError, "receiver has to be a Module" default_value && default and raise ArgumentError, "require either default_falue or default block" if default_value default = -> * { default_value } end name = name.to_s my_id = "__thread_local_#{__id__}__" ObjectSpace.define_finalizer(self, @@cleanup) define_method(name) do values = Thread.current[my_id] ||= {} if default && !values.key?(name) values[name] = default.call end values[name] end define_method("#{name}=") do |value| Thread.current[my_id] ||= {} Thread.current[my_id][name] = value end self end # Define a thread local variable for the current instance with name _name_. # If the value _value_ is given, it is used to initialize the variable. def instance_thread_local(name, default_value = nil, &default) class << self extend Tins::ThreadLocal self end.thread_local name, default_value, &default self end end end tins-1.32.1/lib/tins/secure_write.rb0000644000004100000410000000124414353307475017367 0ustar www-datawww-datamodule Tins module SecureWrite # Write to a file atomically def secure_write(filename, content = nil, mode = 'w') temp = File.new(filename + ".tmp.#$$.#{Time.now.to_f}", mode) if content.nil? and block_given? yield temp elsif !content.nil? temp.write content else raise ArgumentError, "either content or block argument required" end temp.fsync size = temp.stat.size temp.close File.rename temp.path, filename size ensure if temp !temp.closed? and temp.close File.file?(temp.path) and File.unlink temp.path end end end end require 'tins/alias' tins-1.32.1/lib/tins/unit.rb0000644000004100000410000001106314353307475015646 0ustar www-datawww-datarequire 'strscan' require 'bigdecimal' module Tins::Unit Prefix = Struct.new(:name, :step, :multiplier, :fraction) PREFIX_LC = [ '', 'k', 'm', 'g', 't', 'p', 'e', 'z', 'y', ].each_with_index.map { |n, i| Prefix.new(n.freeze, 1000, 1000 ** i, false) }.freeze PREFIX_UC = [ '', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', ].each_with_index.map { |n, i| Prefix.new(n.freeze, 1024, 1024 ** i, false) }.freeze PREFIX_F = [ '', 'm', 'µ', 'n', 'p', 'f', 'a', 'z', 'y', ].each_with_index.map { |n, i| Prefix.new(n.freeze, 1000, 1000 ** -i, true) }.freeze class ParserError < ArgumentError; end module_function def prefixes(identifier) case identifier when :uppercase, :uc, 1024 PREFIX_UC when :lowercase, :lc, 1000 PREFIX_LC when :fraction, :f, 0.001 PREFIX_F when Array identifier end end def format(value, format: '%f %U', prefix: 1024, unit: ?b) prefixes = prefixes(prefix) first_prefix = prefixes.first or raise ArgumentError, 'a non-empty array of prefixes is required' if value.zero? result = format.sub('%U', unit) result %= value else prefix = prefixes[ (first_prefix.fraction ? -1 : 1) * Math.log(value.abs) / Math.log(first_prefix.step) ] result = format.sub('%U', "#{prefix.name}#{unit}") result %= (value / prefix.multiplier.to_f) end end class UnitParser < StringScanner NUMBER = /([+-]? (?:0|[1-9]\d*) (?: \.\d+(?i:e[+-]?\d+) | \.\d+ | (?i:e[+-]?\d+) )? )/x def initialize(source, unit, prefixes = nil) super source if prefixes @unit_re = unit_re(Tins::Unit.prefixes(prefixes), unit) @unit_lc_re = @unit_uc_re = nil else @unit_lc_re = unit_re(Tins::Unit.prefixes(:lc), unit) @unit_uc_re = unit_re(Tins::Unit.prefixes(:uc), unit) @unit_re = nil end @number = 1.0 end def unit_re(prefixes, unit) re = Regexp.new( "(#{prefixes.reverse.map { |pre| Regexp.quote(pre.name) } * ?|})(#{unit})" ) re.singleton_class.class_eval do define_method(:prefixes) { prefixes } end re end private :unit_re attr_reader :number def scan(re) re.nil? and return super end def scan_number scan(NUMBER) or return @number *= BigDecimal(self[1]) end def scan_unit case when scan(@unit_re) prefix = @unit_re.prefixes.find { |pre| pre.name == self[1] } or return @number *= prefix.multiplier when scan(@unit_lc_re) prefix = @unit_lc_re.prefixes.find { |pre| pre.name == self[1] } or return @number *= prefix.multiplier when scan(@unit_uc_re) prefix = @unit_uc_re.prefixes.find { |pre| pre.name == self[1] } or return @number *= prefix.multiplier end end def scan_char(char) scan(/#{char}/) or return end def parse raise NotImplementedError end end class FormatParser < StringScanner def initialize(format, unit_parser) super format @unit_parser = unit_parser end def reset super @unit_parser.reset end def location @unit_parser.peek(10).inspect end private :location def parse reset until eos? || @unit_parser.eos? case when scan(/%f/) @unit_parser.scan_number or raise ParserError, "\"%f\" expected at #{location}" when scan(/%U/) @unit_parser.scan_unit or raise ParserError, "\"%U\" expected at #{location}" when scan(/%%/) @unit_parser.scan_char(?%) or raise ParserError, "#{?%.inspect} expected at #{location}" else char = scan(/./) @unit_parser.scan_char(char) or raise ParserError, "#{char.inspect} expected at #{location}" end end unless eos? && @unit_parser.eos? raise ParserError, "format #{string.inspect} and string "\ "#{@unit_parser.string.inspect} do not match" end @unit_parser.number end end # Parse the string +string+ if it matches +format+ with the unit +unit+ and # the prefixes specified by +prefix+. def parse(string, format: '%f %U', unit: ?b, prefix: nil) prefixes = prefixes(prefix) FormatParser.new(format, UnitParser.new(string, unit, prefixes)).parse end def parse?(string, **options) parse(string, **options) rescue ParserError nil end end tins-1.32.1/lib/tins/temp_io.rb0000644000004100000410000000121014353307475016314 0ustar www-datawww-datarequire 'tmpdir' module Tins module TempIO def temp_io(content: nil, name: __method__) content.nil? and raise ArgumentError, "missing keyword: content" name = File.basename(name.to_s) Dir.mktmpdir do |dir| name = File.join(dir, name) File.open(name, 'w+b') do |io| if content.respond_to?(:call) if content.respond_to?(:arity) && content.arity == 1 content.call(io) else io.write content.call end else io.write content end io.rewind yield io end end end end end tins-1.32.1/lib/tins/complete.rb0000644000004100000410000000056414353307475016503 0ustar www-datawww-datarequire 'readline' module Tins module Complete module_function @@sync = Sync.new def complete(prompt: '', add_hist: false, &block) @@sync.synchronize do Readline.completion_proc = block Readline.input = STDIN Readline.output = STDOUT Readline.readline(prompt, add_hist) end end end end tins-1.32.1/lib/tins/generator.rb0000644000004100000410000000375414353307475016665 0ustar www-datawww-datamodule Tins # This class can create generator objects, that can produce all tuples, that # would be created by as many for-loops as dimensions were given. # # The generator # g = Tins::Generator[1..2, %w[a b c]] # produces # g.to_a # => [[1, "a"], [1, "b"], [1, "c"], [2, "a"], [2, "b"], [2, "c"]] # # The 'each' method can be used to iterate over the tuples # g.each { |a, b| puts "#{a} #{b}" } # and Tins::Generator includes the Enumerable module, so # Enumerable.instance_methods can be used as well: # g.select { |a, b| %w[a c].include? b } # => [[1, "a"], [1, "c"], [2, "a"], [2, "c"]] # class Generator include Enumerable # Create a new Generator object from the enumberables _enums_. def self.[](*enums) new(enums) end # Create a new Generator instance. Use the objects in the Array _enums_ # as dimensions. The should all respond to the :each method (see module # Enumerable in the core ruby library). def initialize(enums) @enums, @iterators, @n = [], [], 0 enums.each { |e| add_dimension(e) } end # Iterate over all tuples produced by this generator and yield to them. def each(&block) # :yield: tuple recurse(&block) self end def recurse(tuple = [ nil ] * @n, i = 0, &block) if i < @n - 1 then @enums[i].__send__(@iterators[i]) do |x| tuple[i] = x recurse(tuple, i + 1, &block) end else @enums[i].__send__(@iterators[i]) do |x| tuple[i] = x yield tuple.dup end end end private :recurse # Add another dimension to this generator. _enum_ is an object, that ought # to respond to the _iterator_ method (defaults to :each). def add_dimension(enum, iterator = :each) @enums << enum @iterators << iterator @n += 1 end # Return the size of this generator, that is the number of its dimensions. def size @enums.size end end end require 'tins/alias' tins-1.32.1/lib/dslkit/0000755000004100000410000000000014353307475014656 5ustar www-datawww-datatins-1.32.1/lib/dslkit/rude.rb0000644000004100000410000000003114353307475016134 0ustar www-datawww-datarequire 'tins/xt/dslkit' tins-1.32.1/lib/dslkit/polite.rb0000644000004100000410000000002614353307475016475 0ustar www-datawww-datarequire 'tins/dslkit' tins-1.32.1/lib/tins.rb0000644000004100000410000000320314353307475014664 0ustar www-datawww-datamodule Tins require 'tins/attempt' require 'tins/bijection' require 'tins/count_by' require 'tins/deep_dup' require 'tins/file_binary' require 'tins/find' require 'tins/generator' require 'tins/go' require 'tins/hash_symbolize_keys_recursive' require 'tins/hash_union' require 'tins/limited' require 'tins/lines_file' require 'tins/memoize' require 'tins/minimize' require 'tins/module_group' require 'tins/named_set' require 'tins/null' require 'tins/once' require 'tins/p' require 'tins/partial_application' require 'tins/range_plus' require 'tins/require_maybe' require 'tins/secure_write' require 'tins/string_camelize' require 'tins/string_underscore' require 'tins/string_version' require 'tins/subhash' require 'tins/time_dummy' require 'tins/date_dummy' require 'tins/date_time_dummy' require 'tins/to_proc' require 'tins/uniq_by' require 'tins/version' require 'tins/write' require 'tins/extract_last_argument_options' require 'tins/deep_const_get' require 'tins/responding' require 'tins/proc_compose' require 'tins/proc_prelude' require 'tins/concern' require 'tins/to' require 'tins/terminal' require 'tins/sexy_singleton' require 'tins/method_description' require 'tins/annotate' require 'tins/token' require 'tins/dslkit' require 'tins/case_predicate' require 'tins/implement' if defined? ::Encoding require 'tins/string_byte_order_mark' end require 'tins/complete' require 'tins/duration' require 'tins/unit' require 'tins/expose' require 'tins/temp_io' require 'tins/temp_io_enum' require 'tins/lru_cache' end require 'tins/alias' tins-1.32.1/lib/dslkit.rb0000644000004100000410000000006214353307475015201 0ustar www-datawww-datarequire 'tins/alias' require 'tins/dslkit/polite' tins-1.32.1/lib/spruz.rb0000644000004100000410000000004414353307475015072 0ustar www-datawww-datarequire 'tins' require 'tins/alias' tins-1.32.1/Gemfile0000644000004100000410000000011714353307475014110 0ustar www-datawww-data# vim: set filetype=ruby et sw=2 ts=2: source 'https://rubygems.org' gemspec